Financial Statement Indicator by zdmreKnowing how to work with the datas in a company's financial statements is an essential skill for stock investors. The meaningful interpretation and analysis of balance sheets, income statements, and cash flow statements to discern a company's investment qualities is the basis for smart investment choices.
You can access to the financials tables of the companies as a summary with this indicator.
3 Tables;
Income Statement Table:
Revenue
Net Profit
EPS
EPS-D
P/E
Balance Sheet Table:
Current Asset
Total Asset
Total Equity
Book Value per Share
Total Debt
Debt/Equity
Statistics & Cash Flow Table:
Return On Equity
Return On Asset
Return On Invested Capital
Quick Ratio
Free Cash Flow
In den Scripts nach " TABLE " suchen
Combined EMA/Smiley & DEM System## 🔷 General Overview
This script creates an advanced technical analysis system for TradingView, combining multiple Exponential Moving Averages (EMAs), Simple Moving Averages (SMAs), dynamic Fibonacci levels, and ATR (Average True Range) analysis. It presents the results clearly through interactive, real-time tables directly on the chart.
---
## 🔹 Indicator Structure
The script consists of two main parts:
### **1. EMA & SMA Combined System with Fibonacci**
- **Purpose:**
Provides visual insights by comparing multiple EMA/SMA periods and identifying significant dynamic price levels using Fibonacci ratios around a calculated "Golden" line.
- **Components:**
- **Moving Averages (MAs)**:
- 20 EMAs (periods from 20 to 400)
- 20 SMAs (also from 20 to 400)
- **Golden Line:**
Calculated as the average of all EMAs and SMAs.
- **Dynamic Fibonacci Levels:**
Key ratios around the Golden line (0.5, 0.618, 0.786, 1.0, 1.272, 1.414, 1.618, 2.0) dynamically adjust based on market conditions.
- **Fibonacci Labels:**
Labels are shown next to Fibonacci lines, indicating their numeric value clearly on the chart.
- **Table (Top Right Corner):**
- Displays:
- **Input:** EMA/SMA periods sorted by their current average price levels.
- **AVG:** The average of corresponding EMA & SMA pairs.
- **EMA & SMA Values:** Individual EMA/SMA values clearly marked.
- **Dynamic Highlighting:** Highlights the row whose average (EMA+SMA)/2 is closest to the current price, helping identify immediate price action significance.
- **Sorting Logic:**
Each EMA/SMA pair is dynamically sorted based on their average values. Color coding (red/green) is used:
- **Green:** EMA/SMA pairs with shorter periods when their average is lower.
- **Red:** EMA/SMA pairs with longer periods when their average is lower.
- **Star (⭐):** Represents the "Golden" average clearly.
---
### **2. DEM System (Dynamic EMA/ATR Metrics)**
- **Purpose:**
Provides detailed ATR statistics to assess market volatility clearly and quickly.
- **Components:**
- **Moving Averages:**
- SMA lines: 25, 50, 100, 200.
- **Bollinger Bands:**
- Based on 20-period SMA of highs and standard deviation of lows.
- **ATR Analysis:**
- ATR calculations for multiple periods (1-day, 10, 20, 30, 40, 50).
- **ATR Premium:** Average ATR of all calculated periods, providing an overarching volatility indicator.
- **ATR Table (Bottom Right Corner):**
- Displays clearly structured ATR values and percentages relative to the current close price:
- Columns: **ATR Period**, **Value**, and **% of Close**.
- Rows: Each specific ATR (1D, 10, 20, 30, 40, 50), plus ATR premium.
- The ATR premium is highlighted in yellow to signify its importance clearly.
---
## 🔹 Key Features and Logic Explained
- **Dynamic EMA/SMA Sorting:**
The script computes the average of each EMA/SMA pair and sorts them dynamically on each bar, highlighting their relative importance visually. This allows traders to easily interpret the strength of current support/resistance levels based on moving averages.
- **Closest EMA/SMA Pair to Current Price:**
Calculates the absolute difference between the current price and all EMA/SMA averages, highlighting the closest one for quick reference.
- **Fibonacci Ratios:**
- Dynamically calculated Fibonacci levels based on the "Golden" EMA/SMA average give clear visual guidance for potential targets, supports, and resistances.
- Labels are continuously updated and placed next to levels for clarity.
- **ATR Volatility Analysis:**
- Provides immediate insight into market volatility with absolute and relative (percentage-based) ATR values.
- ATR premium summarizes volatility across multiple timeframes clearly.
---
## 🔹 Practical Use Case:
- Traders can quickly identify support/resistance and critical price zones through EMA/SMA and Fibonacci combinations.
- Useful in assessing immediate volatility, guiding stop-loss and take-profit levels through detailed ATR metrics.
- The dynamic highlighting in tables provides intuitive, real-time decision support for active traders.
---
## 🔹 How to Use this Script:
1. **Adjust EMA & SMA Lengths** from indicator settings if different periods are preferred.
2. **Monitor dynamic Fibonacci levels** around the "Golden" average to identify possible reversal or continuation points.
3. **Check EMA/SMA table:** Rows highlighted indicate immediate significance concerning current market price.
4. **ATR table:** Use volatility metrics for better risk management.
---
## 🔷 Conclusion
This advanced Pine Script indicator efficiently combines multiple EMAs, SMAs, dynamic Fibonacci retracement levels, and volatility analysis using ATR into a comprehensive real-time analytical tool, enhancing traders' decision-making capabilities by providing clear and actionable insights directly on the TradingView chart.
Uptrick: Alpha TrendIntroduction
Uptrick: Alpha Trend is a comprehensive technical analysis indicator designed to provide traders with detailed insights into market trends, momentum, and risk metrics. It adapts to various trading styles—from quick scalps to longer-term positions—by dynamically adjusting its calculations and visual elements. By combining multiple smoothing techniques, advanced color schemes, and customizable data tables, the indicator offers a holistic view of market behavior.
Originality
The Alpha Trend indicator distinguishes itself by blending established technical concepts with innovative adaptations. It employs three different smoothing techniques tailored to specific trading modes (Scalp, Swing, and Position), and it dynamically adjusts its parameters to match the chosen mode. The indicator also offers a wide range of color palettes and multiple on-screen tables that display key metrics. This unique combination of features, along with its ability to adapt in real time, sets it apart as a versatile tool for both novice and experienced traders.
Features
1. Multi-Mode Trend Line
The indicator automatically selects a smoothing method based on the trading mode:
- Scalp Mode uses the Hull Moving Average (HMA) for rapid responsiveness.
- Swing Mode employs the Exponential Moving Average (EMA) for balanced reactivity.
- Position Mode applies the Weighted Moving Average (WMA) for smoother, long-term trends.
Each method is chosen to best capture the price action dynamics appropriate to the trader’s timeframe.
2. Adaptive Momentum Thresholds
It tracks bullish and bearish momentum with counters that increment as the trend confirms directional movement. When these counters exceed a user-defined threshold, the indicator generates optional buy or sell signals. This approach helps filter out minor fluctuations and highlights significant market moves.
3. Gradient Fills
Two types of fills enhance visual clarity:
- Standard Gradient Fill displays ATR-based zones above and below the trend line, indicating potential bullish and bearish areas.
- Fading Gradient Fill creates a smooth transition between the trend line and the price, visually emphasizing the distance between them.
4. Bar Coloring and Signal Markers
The indicator can color-code bars based on market conditions—bullish, bearish, or neutral—allowing for immediate visual assessment. Additionally, signal markers such as buy and sell arrows are plotted when momentum thresholds are breached.
5. Comprehensive Data Tables
Uptrick: Alpha Trend offers several optional tables for detailed analysis:
- Insider Info: Displays key metrics like the current trend value, bullish/bearish momentum counts, and ATR.
- Indicator Metrics: Lists input settings such as trend length, damping, signal threshold, and net momentum.
- Market Analysis: Summarizes overall trend direction, trend strength, Sortino ratio, return, and volatility.
- Price & Trend Dynamics: Details price deviation from the trend, trend slope, and ATR ratio.
- Momentum & Volatility Insights: Presents RSI, standard deviation (volatility), and net momentum.
- Performance & Acceleration Metrics: Focuses on the Sortino ratio, trend acceleration, return, and trend strength.
Each table can be positioned flexibly on the chart, allowing traders to customize the layout according to their needs.
Why It Combines Specific Smoothing Techniques
Smoothing techniques are essential for filtering out market noise and revealing underlying trends. The indicator combines three smoothing methods for the following reasons:
- The Hull Moving Average (HMA) in Scalp Mode minimizes lag and responds quickly to price changes, which is critical for short-term trading.
- The Exponential Moving Average (EMA) in Swing Mode gives more weight to recent data, striking a balance between speed and smoothness. This makes it suitable for mid-term trend analysis.
- The Weighted Moving Average (WMA) in Position Mode smooths out short-term fluctuations, offering a clear view of longer-term trends and reducing the impact of transient market volatility.
By using these specific methods in their respective trading modes, the indicator ensures that the trend line is appropriately responsive for the intended time frame, enhancing decision-making while maintaining clarity.
Inputs
1. Trend Length (Default: 30)
Defines the lookback period for the smoothing calculation. A shorter trend length results in a more responsive line, while a longer length produces a smoother, less volatile trend.
2. Trend Damping (Default: 0.75)
Controls the degree of smoothing applied to the trend line. Lower values lead to a smoother curve, whereas higher values increase sensitivity to price fluctuations.
3. Signal Strength Threshold (Default: 5)
Specifies the number of consecutive bullish or bearish bars required to trigger a signal. Higher thresholds reduce the frequency of signals, focusing on stronger moves.
4. Enable Bar Coloring (Default: True)
Toggles whether each price bar is colored to indicate bullish, bearish, or neutral conditions.
5. Enable Signals (Default: True)
When enabled, this option plots buy or sell arrows on the chart once the momentum thresholds are met.
6. Enable Standard Gradient Fill (Default: False)
Activates ATR-based gradient fills around the trend line to visualize potential support and resistance zones.
7. Enable Fading Gradient Fill (Default: True)
Draws a gradual color transition between the trend line and the current price, emphasizing their divergence.
8. Trading Mode (Options: Scalp, Swing, Position)
Determines which smoothing method and ATR period to use, adapting the indicator’s behavior to short-term, medium-term, or long-term trading.
9. Table Position Inputs
Allows users to select from nine possible chart positions (top, middle, bottom; left, center, right) for each data table.
10. Show Table Booleans
Separate toggles control the display of each table (Insider Info, Indicator Metrics, Market Analysis, and the three Deep Tables), enabling a customized view of the data.
Color Schemes
(Default) - The colors in the preview image of the indicator.
(Emerald)
(Sapphire)
(Golden Blaze)
(Mystic)
(Monochrome)
(Pastel)
(Vibrant)
(Earth)
(Neon)
Calculations
1. Trend Line Methods
- Scalp Mode: Utilizes the Hull Moving Average (HMA), which computes two weighted moving averages (one at half the length and one at full length), subtracts them, and then applies a final weighted average based on the square root of the length. This method minimizes lag and increases responsiveness.
- Swing Mode: Uses the Exponential Moving Average (EMA), which assigns greater weight to recent prices, thus balancing quick reaction with smoothness.
- Position Mode: Applies the Weighted Moving Average (WMA) to focus on longer-term trends by emphasizing the entire lookback period and reducing the impact of short-term volatility.
2. Momentum Tracking
The indicator maintains separate counters for bullish and bearish momentum. These counters increase as the trend confirms directional movement and reset when the trend reverses. When a counter exceeds the defined signal strength threshold, a corresponding signal (buy or sell) is triggered.
3. Volatility and ATR Zones
The Average True Range (ATR) is calculated using a period that adapts to the selected trading mode (shorter for Scalp, longer for Position). The ATR value is then used to define upper and lower zones around the trend line, highlighting the current level of market volatility.
4. Return and Trend Acceleration
- Return is calculated as the difference between the current and previous closing prices, providing a simple measure of price change.
- Trend Acceleration is derived from the change in the trend line’s movement (its first derivative) compared to the previous bar. This metric indicates whether the trend is gaining or losing momentum.
5. Sortino Ratio and Standard Deviation
- The Sortino Ratio measures risk-adjusted performance by comparing returns to downside volatility (only considering negative price changes).
- Standard Deviation is computed over the lookback period to assess the extent of price fluctuations, offering insights into market stability.
Usage
This indicator is suitable for various time frames and market instruments. Traders can enable or disable specific visual elements such as gradient fills, bar coloring, and signal markers based on their preference. For a minimalist approach, one might choose to display only the primary trend line. For a deeper analysis, enabling multiple tables can provide extensive data on momentum, volatility, trend dynamics, and risk metrics.
Important Note on Risk
Trading involves inherent risk, and no indicator can eliminate the uncertainty of the markets. Past performance is not indicative of future results. It is essential to use proper risk management, test any new tool thoroughly, and consult multiple sources or professional advice before making trading decisions.
Conclusion
Uptrick: Alpha Trend unifies a diverse set of calculations, adaptive smoothing techniques, and customizable visual elements into one powerful tool. By combining the Hull, Exponential, and Weighted Moving Averages, the indicator is able to provide a trend line that is both responsive and smooth, depending on the trading mode. Its advanced color schemes, gradient fills, and detailed data tables deliver a comprehensive analysis of market trends, momentum, and risk. Whether you are a short-term trader or a long-term investor, this indicator aims to clarify price action and assist you in making more informed trading decisions.
Percentage price changeThis indicator marks bars whose values increase or decrease by an amount greater than or equal to the value of the specified parameter as a percentage. Bars that meet the condition are marked with labels, boxes and colors. In addition to the standard method of calculating the percentage change at the closing price of the current and previous bars, the indicator allows you to choose non-standard calculation methods (at the prices of opening and closing the current bar, as well as at the prices of the maximum at the minimum of the current bar). You can choose to display the percentage changes of individual bars as well as a series of bars. You can select the number of bars in a series of bars. You can also apply filters by the direction of the bars in the series or by the percentage of individual bars in the series.
It is important to remember that in version 5 of Pine Script™, the maximum possible number of labels and the maximum possible number of boxes cannot exceed 500!
There are several main parameters that can be changed in section PARAMETERS FOR CALCULATION:
1. 'Bars count' - The number of bars for which the percentage rise or fall is calculated.
2. ‘Percentage change’ - sets the price change as a percentage. Bars with a price range above or equal to the specified value will be marked on the chart.
3. ‘First and second points of calculation’ - the first and second points for calculating the percentage change. Here you can set several different values for the calculation:
- 'Cl.pr., Close' - Closing price of the previous bar and closing price of the current bar (or a series of bars) (these values are used for the standard calculation of the percentage change on the chart).
- 'Open, Close' - Opening and closing prices of the current bar (or a series of bars).
- 'High|Low' - Highest and lowest price of the current bar (or a series of bars).
- 'Cl.pr.|High|Low' - Highest or lowest price of the current bar (or a series of bars) (depending on whether the bar is going up or down) or closing price of the previous bar for first point (one of these values is automatically selected, which gives a larger result, depending on whether there is a gap between these values). Highest or lowest price of the current bar for second point.
In the LIMITS section, you can set the following parameters.
1. ‘Only for the last bar’ - If this option is selected, the indicator will be applied only for the last bar (or series of bars).
2. 'Only bars in one direction' - A condition that takes into account sequences from the selected number of bars going in only one direction. If at least one bar has a different direction from the other bars, then such a sequence will not be taken into account. This only works if the 'Bars count' is > 1.
3. "Cut off higher values" - This field cuts off higher values. Bars with a price range above or equal to the specified value will not be marked on the chart. This can be used in some cases to make the chart less loaded with data and more visual. Of course, you can also use this option however you want.
4. ‘Min percent in series of bars’ - If the value 'Number of bars' is > 1, then a series of bars is taken into account, in which the percentage change of individual bars is greater than or equal to the set value.
In the DATE RANGE section, you can set the limits of the time and date range in which the calculation will be performed. In some cases, this can be used in order not to exceed the limit on the number of labels or boxes, which cannot exceed 500. Of course, you can also use this option however you want. By default, the date range is unlimited.
'Timezone offset, hours' - It is used only for the correct display of the limits of the date range in the parameter table.
In the PRICE INCREASE LABELS and PRICE REDUCTION LABELS section, you can define the design of labels bars and boxes, such as colors, shapes, sizes, and location. You can set the colors of the bars separately on the Style tab. On the Style tab, you can also turn on/off the display of frames, labels and color markings of bars.
The PARAMETER TABLE section is designed to adjust the display of the table for a more visual display of the selected values of all parameters on the Arguments tab. Depending on which values have been set and which parameters have been enabled or disabled, the table will change its appearance, display or hide some rows. A single line 'Total found' will be displayed all the time. It shows the count of bars that meet the condition and count of labels or boxes used in the diagram. Since the bars are labeled with labels or boxes, their number cannot exceed 500 for Pine script version 5.
1. 'Pos.' - sets the main position of the table on the screen.
2. 'X off.', 'Y off.' - You can set the offset of the table along the X and Y axes. This option can be useful to avoid overlapping multiple tables if you want to use two or more instances of this indicator on your chart. The minimum value is -30, the maximum is 30. Positive values shift the table to the right on the X axis and up on the Y axis. Negative values shift the table to the left on the X axis and down on the Y axis.
3. 'Font color' - The font color in the table.
'Warn. font color', 'Warn. backgr. color' - The font and background colors in the 'Total found' row in the table. If the number of labels or boxes exceeds 500, the font and background will be colored in these colors.
4. ‘Font size’ – Sets the font size in the table.
5. 'Show hours and minutes in date/time range' - changes the date and time format of time range from {yyyy.MM.dd HH:mm} to {yyyy.MM.dd}.
6. 'View all params' - used to display all parameters, even those duplicated in the main line of the indicator.
7. ‘Title’ – If desired, you can make a header for the table.
The last row of the table shows the number of bars found that meet the conditions. Since these bars are marked with labels (in the case of one bar) or boxes (in the case of series of bars), the limit that can be marked on the chart is 500. Exceeding this value will be displayed in the table and additionally highlighted in red font. This will signal that not all bars found are displayed on the chart.
On the Style tab, you can turn the table display on/off.
[SGM Auto Regressiv - significant lags only]This Pine Script™ is designed for traders seeking advanced statistical analysis based on autoregressive (AR) models, with automatic filtering of significant lags according to a customizable confidence threshold.
Key Features:
AR(p) Model with Significance Filtering:
Only statistically significant lags (based on the selected confidence level) are included in the model calculations.
Coefficient Weighting Options:
Uniform weighting.
Weighting based on the t-statistic.
Visualization of Key Indicators:
Dynamic plotting of autoregressive values, upper and lower bounds (based on standard deviation).
Buy ("Buy") and Sell ("Sell") signals when values exceed the defined bounds.
Robust Analysis:
Calculation of statistical parameters: T-stat, p-value, skewness, kurtosis, r², and the Jarque-Bera test to assess the robustness and normality of residuals.
Summary of results displayed in a visual table for simplified interpretation.
Interactive Tables:
Display of lags, coefficients, t-statistics, p-values, and their significance via a dynamic table.
Overall robustness indicator and interpretation of results ("Good," "Non-significant," etc.).
Easy Customization:
Adjustable confidence level (90% to 99%).
Configurable lengths for moving average and standard deviation to fine-tune signal thresholds.
Benefits for Traders:
Effortless Analysis:
Automatically identifies significant relationships between past and present values, removing unnecessary assumptions.
Enhanced Accuracy:
Filters signals based on rigorous statistical criteria to avoid false signals.
Clear Visualization:
Interactive tables and plots to quickly understand critical parameters.
Default Configuration:
Confidence level: 95%.
Lag weighting: Uniform.
Moving average length: 20 periods.
Standard deviation length: 15 periods.
Usage Recommendations:
Ideal for analyzing volatile assets or identifying potential reversal zones.
Use alongside other indicators to confirm signals.
Prev-Day POC Hit Rate (v6, RTH, tolerance)//@version=6
indicator("Prev-Day POC Hit Rate (v6, RTH, tolerance)", overlay=true)
// ---- Inputs
sessionStr = input.session("0930-1600", "RTH session (exchange time)")
tolPoints = input.float(0.10, "Tolerance (points)")
tolPercent = input.float(0.10, "Tolerance (%) of prev POC")
showMarks = input.bool(true, "Show touch markers")
// ---- RTH gating in exchange TZ
sessFlag = time(timeframe.period, sessionStr)
inRTH = not na(sessFlag)
rthOpen = inRTH and not inRTH
rthClose = (not inRTH) and inRTH
// ---- Prior-day POC proxy = price of highest-volume 1m bar of prior RTH
var float prevPOC = na
var float curPOC = na
var float curMaxVol = 0.0
// ---- Daily hit stats
var bool hitToday = false
var int days = 0
var int hits = 0
// Finalize a day at RTH close (count touch to prevPOC)
if rthClose and not na(prevPOC)
days += 1
if hitToday
hits += 1
// Roll today's POC to prevPOC at next RTH open; reset builders/flags
if rthOpen
prevPOC := curPOC
curPOC := na
curMaxVol := 0.0
hitToday := false
// Build today's proxy POC during RTH (highest-volume 1m bar)
if inRTH
if volume > curMaxVol
curMaxVol := volume
curPOC := close // swap to (high+low+close)/3 if you prefer HLC3
// ---- Touch test against prevPOC (band = max(points, % of prevPOC))
bandPts = na(prevPOC) ? na : math.max(tolPoints, prevPOC * tolPercent * 0.01)
touched = inRTH and not na(prevPOC) and high >= (prevPOC - bandPts) and low <= (prevPOC + bandPts)
if touched
hitToday := true
// ---- Plots
plot(prevPOC, "Prev RTH POC (proxy)", color=color.new(color.fuchsia, 0), linewidth=2, style=plot.style_linebr)
bgcolor(hitToday and inRTH ? color.new(color.green, 92) : na)
plotshape(showMarks and touched ? prevPOC : na, title="Touch prev POC",
style=shape.circle, location=location.absolute, size=size.tiny, color=color.new(color.aqua, 0))
// ---- On-chart stats
hitPct = days > 0 ? (hits * 100.0 / days) : na
var table T = table.new(position.top_right, 2, 3, border_width=1)
if barstate.islastconfirmedhistory
table.cell(T, 0, 0, "Days")
table.cell(T, 1, 0, str.tostring(days))
table.cell(T, 0, 1, "Hits")
table.cell(T, 1, 1, str.tostring(hits))
table.cell(T, 0, 2, "Hit %")
table.cell(T, 1, 2, na(hitPct) ? "—" : str.tostring(hitPct, "#.0") + "%")
Hawkes Volatility Exit IndicatorOverview
The Hawkes Volatility Exit Indicator is a powerful tool designed to help traders capitalize on volatility breakouts and exit positions when momentum fades. Built on the Hawkes process, it models volatility clustering to identify optimal entry points after quiet periods and exit signals during volatility cooling. Designed to be helpful for swing traders and trend followers across markets like stocks, forex, and crypto.
Key Features Volatility-Based Entries: Detects breakouts when volatility spikes above the 95th percentile (adjustable) after quiet periods (below 5th percentile).
This indicator is probably better on exits than entries.
Smart Exit Signals: Triggers exits when volatility drops below a customizable threshold (default: 30th percentile) after a minimum hold period.
Hawkes Process: Uses a decay-based model (kappa) to capture volatility clustering, making it responsive to market dynamics.
Visual Clarity: Includes a volatility line, exit threshold, percentile bands, and intuitive markers (triangles for entries, X for exits).
Status Table: Displays real-time data on position (LONG/SHORT/FLAT), volatility regime (HIGH/LOW/NORMAL), bars held, and exit readiness.
Customizable Alerts: Set alerts for breakouts and exits to stay on top of trading opportunities.
How It Works Quiet Periods: Identifies low volatility (below 5th percentile) that often precede significant moves.
Breakout Entries: Signals bullish (triangle up) or bearish (triangle down) entries when volatility spikes post-quiet period.
Exit Signals: Suggests exiting when volatility cools below the exit threshold after a minimum hold (default: 3 bars).
Visuals & Table: Tracks volatility, position status, and signals via lines, shaded zones, and a detailed status table.
Settings
Hawkes Kappa (0.1): Adjusts volatility decay (lower = smoother, higher = more sensitive).
Volatility Lookback (168): Sets the period for percentile calculations.
ATR Periods (14): Normalizes volatility using Average True Range.
Breakout Threshold (95%): Volatility percentile for entries.
Exit Threshold (30%): Volatility percentile for exits.
Quiet Threshold (5%): Defines quiet periods.
Minimum Hold Bars (3): Ensures positions are held before exiting.
Alerts: Enable/disable breakout and exit alerts.
How to Use
Entries: Look for triangle markers (up for long, down for short) and confirm with the status table showing "ENTRY" and "LONG"/"SHORT."
Exits: Exit on X cross markers when the status table shows "EXIT" and "Exit Ready: YES."
Monitoring: Use the status table to track position, bars held, and volatility regime (HIGH/LOW/NORMAL).
Combine: Pair with price action, support/resistance, or other indicators for better context.
Tips : Adjust thresholds for your market: lower breakout thresholds for more signals, higher exit thresholds for earlier exits.
Test on your asset to ensure compatibility (best for markets with volatility clustering).
Use alerts to automate signal detection.
Limitations Requires sufficient data (default: 168 bars) for reliable signals. Check "Data Status" in the table.
Focuses on volatility, not price direction—combine with trend tools.
May lag slightly due to the smoothing nature of the Hawkes process.
Why Use It?
The Hawkes Volatility Exit Indicator offers a unique, data-driven approach to timing trades based on volatility dynamics. Its clear visuals, customizable settings, and real-time status table make it a valuable addition to any trader’s toolkit. Try it to catch breakouts and exit with precision!
This indicator is based on neurotrader888's python repo. All credit to him. All mistakes mine.
This conversion published for wider attention to the Hawkes method.
Staccked SMA - Regime Switching & Persistance StatisticsThis indicator is designed to identify the prevailing market regime by analyzing the behavior of a "stack" of Simple Moving Averages (SMAs). It helps you understand whether the market is currently trending, mean-reverting, or moving randomly.
Core Concept: SMA Correlation
At its heart, the indicator examines the relationship between a set of nine SMAs with different lengths (3, 5, 8, 13, 21, 34, 55, 89, 144) and the lengths themselves.
In a strong trending market (either up or down), the SMAs will be neatly "stacked" in order of their length. The shortest SMA will be furthest from the longest SMA, creating a strong, almost linear visual pattern. When we measure the statistical correlation between the SMA values and their corresponding lengths, we get a value close to +1 (perfect uptrend stack) or -1 (perfect downtrend stack). The absolute value of this correlation will be very high (close to 1).
In a mean-reverting or sideways market, the SMAs will be tangled and crisscrossing each other. There is no clear order, and the relationship between an SMA's length and its price value is weak. The correlation will be close to 0.
This indicator calculates this Pearson correlation on every bar, giving a continuous measure of how ordered or "trendy" the SMAs are. An absolute correlation above 0.8 is considered strongly trending, while a value between 0.4 and 0.8 suggests a mean-reverting character. Below 0.4, the market is likely random or choppy.
Regime Classification and Statistics
The indicator doesn't just look at the current correlation; it analyzes its behavior over a user-defined lookback window (default is 252 bars) to classify the overall market "regime."
It presents its findings in a clear table:
📊 |SMA Correlation| Regime Table: This main table provides a snapshot of the current market character.
Median: Shows the median absolute correlation over the lookback period, giving a central tendency of the market's behavior.
% > 0.80: The percentage of time the market was in a strong trend during the lookback period.
% < 0.80 & > 0.40: The percentage of time the market showed mean-reverting characteristics.
🧠 Regime: The final classification. It's labeled "📈 Trend-Dominant" if the median correlation is high and it has spent a significant portion of the time trending. It's labeled "🔄 Mean-Reverting" if the median is in the middle range and it has spent significant time in that state. Otherwise, it's considered "⚖️ Random/ Choppy".
📐 Regime Significance: This tells you how statistically confident you can be in the current regime classification, using a Z-score to compare its occurrence against random chance. ⭐⭐⭐ indicates high confidence (99%), while "❌ Not Significant" means the pattern could be random.
Regime Transition Probabilities
Optionally, a second table can be displayed that shows the historical probability of the market transitioning from one regime to another over different time horizons (t+5, t+10, t+15, and t+20 bars).
📈 → 🔄 → ⚖️ Transition Table: This table answers questions like, "If the market is trending now (From: 📈), what is the probability it will be mean-reverting (→ 🔄) in 10 bars?"
This provides powerful insights into the market's cyclical nature, helping you anticipate future behavior based on past patterns. For example, you might find that after a period of strong trending, a transition to a choppy state is more likely than a direct switch to a mean-reverting
Indicator Settings
Lookback Window for Regime Classification: This sets the number of recent bars (default is 252) the script analyzes to determine the current market regime (Trending, Mean-Reverting, or Random). A larger number provides a more stable, long-term view, while a smaller number makes the classification more sensitive to recent price action.
Show Regime Transition Table: A simple toggle (on/off) to show or hide the table that displays the probabilities of the market switching from one regime to another.
Lookback Offset for Starting Regime: This determines the "starting point" in the past for calculating regime transitions. The default is 20 bars ago. The script looks at the regime at this point and then checks what it became at later points.
Step 1, 2, 3, 4 Offset (bars): These define the future time intervals (5, 10, 15, and 20 bars by default) for the transition probability table. For example, the script checks the regime at the "Lookback Offset" and then sees what it transitioned to 5, 10, 15, and 20 bars later.
Significance Filter Settings
Use Regime Significance Filter: When enabled, this filter ensures that the regime transition statistics only count transitions that were "statistically significant." This helps to filter out noise and focus on more reliable patterns.
Min Stars Required (1=90%, 2=95%, 3=99%): This sets the minimum confidence level required for a regime to be included in the transition statistics when the significance filter is on.
1 ⭐: Requires at least 90% confidence.
2 ⭐⭐: Requires at least 95% confidence (default).
3 ⭐⭐⭐: Requires at least 99% confidence.
Intraday Volume Pulse GSK-VIZAG-AP-INDIAIntraday Volume Pulse Indicator
Overview
This indicator is designed to track and visualize intraday volume dynamics during a user-defined trading session. It calculates and displays key volume metrics such as buy volume, sell volume, cumulative delta (difference between buy and sell volumes), and total volume. The data is presented in a customizable table overlay on the chart, making it easy to monitor volume pulses throughout the session. This can help traders identify buying or selling pressure in real-time, particularly useful for intraday strategies.
The indicator resets its calculations at the start of each new day and only accumulates volume data from the specified session start time onward. It uses simple logic to classify volume as buy or sell based on candle direction:
Buy Volume: Assigned to green (up) candles or half of neutral (doji) candles.
Sell Volume: Assigned to red (down) candles or half of neutral (doji) candles.
All calculations are approximate and based on available volume data from the chart. This script does not incorporate external data sources, order flow, or tick-level information—it's purely derived from standard OHLCV (Open, High, Low, Close, Volume) bars.
Key Features
Session Customization: Define the start time of your trading session (e.g., market open) and select from common timezones like Asia/Kolkata, America/New_York, etc.
Volume Metrics:
Buy Volume: Total volume attributed to bullish activity.
Sell Volume: Total volume attributed to bearish activity.
Cumulative Delta: Net difference (Buy - Sell), highlighting overall market bias.
Total Volume: Sum of all volume during the session.
Formatted Display: Volumes are formatted for readability (e.g., in thousands "K", lakhs "L", or crores "Cr" for large numbers).
Color-Coded Table: Uses a patriotic color scheme inspired by general themes (Saffron, White, Green) with dynamic backgrounds based on positive/negative values for quick visual interpretation.
Table Options: Toggle visibility and position (top-right, top-left, etc.) for a clean chart layout.
How to Use
Add to Chart: Apply this indicator to any symbol's chart (works best on intraday timeframes like 1-min, 5-min, or 15-min).
Configure Inputs:
Session Start Hour/Minute: Set to your market's open time (default: 9:15 for Indian markets).
Timezone: Choose the appropriate timezone to align with your trading hours.
Show Table: Enable/disable the metrics table.
Table Position: Place the table where it doesn't obstruct your view.
Interpret the Table:
Monitor for spikes in buy/sell volume or shifts in cumulative delta.
Positive delta (green) suggests buying pressure; negative (red) suggests selling.
Use alongside price action or other indicators for confirmation—e.g., high total volume with positive delta could indicate bullish momentum.
Limitations:
Volume classification is heuristic and not based on actual order flow (e.g., it splits doji volume evenly).
Data accumulation starts from the session time and resets daily; historical backtesting may be limited by the max_bars_back=500 setting.
This is for educational and visualization purposes only—do not use as sole basis for trading decisions.
Calculation Details
Session Filter: Uses timestamp() to define the session start and filters bars with time >= sessionStart.
New Day Detection: Resets volumes on daily changes via ta.change(time("D")).
Volume Assignment:
Buy: Full volume if close > open; half if close == open.
Sell: Full volume if close < open; half if close == open.
Cumulative Metrics: Accumulated only during the session.
Formatting: Custom function f_format() scales large numbers for brevity.
Disclaimer
This script is for educational and informational purposes only. It does not provide financial advice or signals to buy/sell any security. Always perform your own analysis and consult a qualified financial professional before making trading decisions.
© 2025 GSK-VIZAG-AP-INDIA
Game Theory Trading StrategyGame Theory Trading Strategy: Explanation and Working Logic
This Pine Script (version 5) code implements a trading strategy named "Game Theory Trading Strategy" in TradingView. Unlike the previous indicator, this is a full-fledged strategy with automated entry/exit rules, risk management, and backtesting capabilities. It uses Game Theory principles to analyze market behavior, focusing on herd behavior, institutional flows, liquidity traps, and Nash equilibrium to generate buy (long) and sell (short) signals. Below, I'll explain the strategy's purpose, working logic, key components, and usage tips in detail.
1. General Description
Purpose: The strategy identifies high-probability trading opportunities by combining Game Theory concepts (herd behavior, contrarian signals, Nash equilibrium) with technical analysis (RSI, volume, momentum). It aims to exploit market inefficiencies caused by retail herd behavior, institutional flows, and liquidity traps. The strategy is designed for automated trading with defined risk management (stop-loss/take-profit) and position sizing based on market conditions.
Key Features:
Herd Behavior Detection: Identifies retail panic buying/selling using RSI and volume spikes.
Liquidity Traps: Detects stop-loss hunting zones where price breaks recent highs/lows but reverses.
Institutional Flow Analysis: Tracks high-volume institutional activity via Accumulation/Distribution and volume spikes.
Nash Equilibrium: Uses statistical price bands to assess whether the market is in equilibrium or deviated (overbought/oversold).
Risk Management: Configurable stop-loss (SL) and take-profit (TP) percentages, dynamic position sizing based on Game Theory (minimax principle).
Visualization: Displays Nash bands, signals, background colors, and two tables (Game Theory status and backtest results).
Backtesting: Tracks performance metrics like win rate, profit factor, max drawdown, and Sharpe ratio.
Strategy Settings:
Initial capital: $10,000.
Pyramiding: Up to 3 positions.
Position size: 10% of equity (default_qty_value=10).
Configurable inputs for RSI, volume, liquidity, institutional flow, Nash equilibrium, and risk management.
Warning: This is a strategy, not just an indicator. It executes trades automatically in TradingView's Strategy Tester. Always backtest thoroughly and use proper risk management before live trading.
2. Working Logic (Step by Step)
The strategy processes each bar (candle) to generate signals, manage positions, and update performance metrics. Here's how it works:
a. Input Parameters
The inputs are grouped for clarity:
Herd Behavior (🐑):
RSI Period (14): For overbought/oversold detection.
Volume MA Period (20): To calculate average volume for spike detection.
Herd Threshold (2.0): Volume multiplier for detecting herd activity.
Liquidity Analysis (💧):
Liquidity Lookback (50): Bars to check for recent highs/lows.
Liquidity Sensitivity (1.5): Volume multiplier for trap detection.
Institutional Flow (🏦):
Institutional Volume Multiplier (2.5): For detecting large volume spikes.
Institutional MA Period (21): For Accumulation/Distribution smoothing.
Nash Equilibrium (⚖️):
Nash Period (100): For calculating price mean and standard deviation.
Nash Deviation (0.02): Multiplier for equilibrium bands.
Risk Management (🛡️):
Use Stop-Loss (true): Enables SL at 2% below/above entry price.
Use Take-Profit (true): Enables TP at 5% above/below entry price.
b. Herd Behavior Detection
RSI (14): Checks for extreme conditions:
Overbought: RSI > 70 (potential herd buying).
Oversold: RSI < 30 (potential herd selling).
Volume Spike: Volume > SMA(20) x 2.0 (herd_threshold).
Momentum: Price change over 10 bars (close - close ) compared to its SMA(20).
Herd Signals:
Herd Buying: RSI > 70 + volume spike + positive momentum = Retail buying frenzy (red background).
Herd Selling: RSI < 30 + volume spike + negative momentum = Retail selling panic (green background).
c. Liquidity Trap Detection
Recent Highs/Lows: Calculated over 50 bars (liquidity_lookback).
Psychological Levels: Nearest round numbers (e.g., $100, $110) as potential stop-loss zones.
Trap Conditions:
Up Trap: Price breaks recent high, closes below it, with a volume spike (volume > SMA x 1.5).
Down Trap: Price breaks recent low, closes above it, with a volume spike.
Visualization: Traps are marked with small red/green crosses above/below bars.
d. Institutional Flow Analysis
Volume Check: Volume > SMA(20) x 2.5 (inst_volume_mult) = Institutional activity.
Accumulation/Distribution (AD):
Formula: ((close - low) - (high - close)) / (high - low) * volume, cumulated over time.
Smoothed with SMA(21) (inst_ma_length).
Accumulation: AD > MA + high volume = Institutions buying.
Distribution: AD < MA + high volume = Institutions selling.
Smart Money Index: (close - open) / (high - low) * volume, smoothed with SMA(20). Positive = Smart money buying.
e. Nash Equilibrium
Calculation:
Price mean: SMA(100) (nash_period).
Standard deviation: stdev(100).
Upper Nash: Mean + StdDev x 0.02 (nash_deviation).
Lower Nash: Mean - StdDev x 0.02.
Conditions:
Near Equilibrium: Price between upper and lower Nash bands (stable market).
Above Nash: Price > upper band (overbought, sell potential).
Below Nash: Price < lower band (oversold, buy potential).
Visualization: Orange line (mean), red/green lines (upper/lower bands).
f. Game Theory Signals
The strategy generates three types of signals, combined into long/short triggers:
Contrarian Signals:
Buy: Herd selling + (accumulation or down trap) = Go against retail panic.
Sell: Herd buying + (distribution or up trap).
Momentum Signals:
Buy: Below Nash + positive smart money + no herd buying.
Sell: Above Nash + negative smart money + no herd selling.
Nash Reversion Signals:
Buy: Below Nash + rising close (close > close ) + volume > MA.
Sell: Above Nash + falling close + volume > MA.
Final Signals:
Long Signal: Contrarian buy OR momentum buy OR Nash reversion buy.
Short Signal: Contrarian sell OR momentum sell OR Nash reversion sell.
g. Position Management
Position Sizing (Minimax Principle):
Default: 1.0 (10% of equity).
In Nash equilibrium: Reduced to 0.5 (conservative).
During institutional volume: Increased to 1.5 (aggressive).
Entries:
Long: If long_signal is true and no existing long position (strategy.position_size <= 0).
Short: If short_signal is true and no existing short position (strategy.position_size >= 0).
Exits:
Stop-Loss: If use_sl=true, set at 2% below/above entry price.
Take-Profit: If use_tp=true, set at 5% above/below entry price.
Pyramiding: Up to 3 concurrent positions allowed.
h. Visualization
Nash Bands: Orange (mean), red (upper), green (lower).
Background Colors:
Herd buying: Red (90% transparency).
Herd selling: Green.
Institutional volume: Blue.
Signals:
Contrarian buy/sell: Green/red triangles below/above bars.
Liquidity traps: Red/green crosses above/below bars.
Tables:
Game Theory Table (Top-Right):
Herd Behavior: Buying frenzy, selling panic, or normal.
Institutional Flow: Accumulation, distribution, or neutral.
Nash Equilibrium: In equilibrium, above, or below.
Liquidity Status: Trap detected or safe.
Position Suggestion: Long (green), Short (red), or Wait (gray).
Backtest Table (Bottom-Right):
Total Trades: Number of closed trades.
Win Rate: Percentage of winning trades.
Net Profit/Loss: In USD, colored green/red.
Profit Factor: Gross profit / gross loss.
Max Drawdown: Peak-to-trough equity drop (%).
Win/Loss Trades: Number of winning/losing trades.
Risk/Reward Ratio: Simplified Sharpe ratio (returns / drawdown).
Avg Win/Loss Ratio: Average win per trade / average loss per trade.
Last Update: Current time.
i. Backtesting Metrics
Tracks:
Total trades, winning/losing trades.
Win rate (%).
Net profit ($).
Profit factor (gross profit / gross loss).
Max drawdown (%).
Simplified Sharpe ratio (returns / drawdown).
Average win/loss ratio.
Updates metrics on each closed trade.
Displays a label on the last bar with backtest period, total trades, win rate, and net profit.
j. Alerts
No explicit alertconditions defined, but you can add them for long_signal and short_signal (e.g., alertcondition(long_signal, "GT Long Entry", "Long Signal Detected!")).
Use TradingView's alert system with Strategy Tester outputs.
3. Usage Tips
Timeframe: Best for H1-D1 timeframes. Shorter frames (M1-M15) may produce noisy signals.
Settings:
Risk Management: Adjust sl_percent (e.g., 1% for volatile markets) and tp_percent (e.g., 3% for scalping).
Herd Threshold: Increase to 2.5 for stricter herd detection in choppy markets.
Liquidity Lookback: Reduce to 20 for faster markets (e.g., crypto).
Nash Period: Increase to 200 for longer-term analysis.
Backtesting:
Use TradingView's Strategy Tester to evaluate performance.
Check win rate (>50%), profit factor (>1.5), and max drawdown (<20%) for viability.
Test on different assets/timeframes to ensure robustness.
Live Trading:
Start with a demo account.
Combine with other indicators (e.g., EMAs, support/resistance) for confirmation.
Monitor liquidity traps and institutional flow for context.
Risk Management:
Always use SL/TP to limit losses.
Adjust position_size for risk tolerance (e.g., 5% of equity for conservative trading).
Avoid over-leveraging (pyramiding=3 can amplify risk).
Troubleshooting:
If no trades are executed, check signal conditions (e.g., lower herd_threshold or liquidity_sensitivity).
Ensure sufficient historical data for Nash and liquidity calculations.
If tables overlap, adjust position.top_right/bottom_right coordinates.
4. Key Differences from the Previous Indicator
Indicator vs. Strategy: The previous code was an indicator (VP + Game Theory Integrated Strategy) focused on visualization and alerts. This is a strategy with automated entries/exits and backtesting.
Volume Profile: Absent in this strategy, making it lighter but less focused on high-volume zones.
Wick Analysis: Not included here, unlike the previous indicator's heavy reliance on wick patterns.
Backtesting: This strategy includes detailed performance metrics and a backtest table, absent in the indicator.
Simpler Signals: Focuses on Game Theory signals (contrarian, momentum, Nash reversion) without the "Power/Ultra Power" hierarchy.
Risk Management: Explicit SL/TP and dynamic position sizing, not present in the indicator.
5. Conclusion
The "Game Theory Trading Strategy" is a sophisticated system leveraging herd behavior, institutional flows, liquidity traps, and Nash equilibrium to trade market inefficiencies. It’s designed for traders who understand Game Theory principles and want automated execution with robust risk management. However, it requires thorough backtesting and parameter optimization for specific markets (e.g., forex, crypto, stocks). The backtest table and visual aids make it easy to monitor performance, but always combine with other analysis tools and proper capital management.
If you need help with backtesting, adding alerts, or optimizing parameters, let me know!
Uptrick: Z-Trend BandsOverview
Uptrick: Z-Trend Bands is a Pine Script overlay crafted to capture high-probability mean-reversion opportunities. It dynamically plots upper and lower statistical bands around an EMA baseline by converting price deviations into z-scores. Once price moves outside these bands and then reenters, the indicator verifies that momentum is genuinely reversing via an EMA-smoothed RSI slope. Signal memory ensures only one entry per momentum swing, and traders receive clear, real-time feedback through customizable bar-coloring modes, a semi-transparent fill highlighting the statistical zone, concise “Up”/“Down” labels, and a live five-metric scoring table.
Introduction
Markets often oscillate between trending and reverting, and simple thresholds or static envelopes frequently misfire when volatility shifts. Standard deviation quantifies how “wide” recent price moves have been, and a z-score transforms each deviation into a measure of how rare it is relative to its own history. By anchoring these bands to an exponential moving average, the script maintains a fluid statistical envelope that adapts instantly to both calm and turbulent regimes. Meanwhile, the Relative Strength Index (RSI) tracks momentum; smoothing RSI with an EMA and observing its slope filters out erratic spikes, ensuring that only genuine momentum flips—upward for longs and downward for shorts—qualify.
Purpose
This indicator is purpose-built for short-term mean-reversion traders operating on lower–timeframe charts. It reveals when price has strayed into the outer 5 percent of its recent range, signaling an increased likelihood of a bounce back toward fair value. Rather than firing on price alone, it demands that momentum follow suit: the smoothed RSI slope must flip in the opposite direction before any trade marker appears. This dual-filter approach dramatically reduces noise-driven, false setups. Traders then see immediate visual confirmation—bar colors that reflect the latest signal and age over time, clear entry labels, and an always-visible table of metric scores—so they can gauge both the validity and freshness of each signal at a glance.
Originality and Uniqueness
Uptrick: Z-Trend Bands stands apart from typical envelope or oscillator tools in four key ways. First, it employs fully normalized z-score bands, meaning ±2 always captures roughly the top and bottom 5 percent of moves, regardless of volatility regime. Second, it insists on two simultaneous conditions—price reentry into the bands and a confirming RSI slope flip—dramatically reducing whipsaw signals. Third, it uses slope-phase memory to lock out duplicate signals until momentum truly reverses again, enforcing disciplined entries. Finally, it offers four distinct bar-coloring schemes (solid reversal, fading reversal, exceeding bands, and classic heatmap) plus a dynamic scoring table, rather than a single, opaque alert, giving traders deep insight into every layer of analysis.
Why Each Component Was Picked
The EMA baseline was chosen for its blend of responsiveness—weighting recent price heavily—and smoothness, which filters market noise. Z-score deviation bands standardize price extremes relative to their own history, adapting automatically to shifting volatility so that “extreme” always means statistically rare. The RSI, smoothed with an EMA before slope calculation, captures true momentum shifts without the false spikes that raw RSI often produces. Slope-phase memory flags prevent repeated alerts within a single swing, curbing over-trading in choppy conditions. Bar-coloring modes provide flexible visual contexts—whether you prefer to track the latest reversal, see signal age, highlight every breakout, or view a continuous gradient—and the scoring table breaks down all five core checks for complete transparency.
Features
This indicator offers a suite of configurable visual and logical tools designed to make reversal signals both robust and transparent:
Dynamic z-score bands that expand or contract in real time to reflect current volatility regimes, ensuring the outer ±zThreshold levels always represent statistically rare extremes.
A smooth EMA baseline that weights recent price more heavily, serving as a fair-value anchor around which deviations are measured.
EMA-smoothed RSI slope confirmation, which filters out erratic momentum spikes by first smoothing raw RSI and then requiring its bar-to-bar slope to flip before any signal is allowed.
Slope-phase memory logic that locks out duplicate buy or sell markers until the RSI slope crosses back through zero, preventing over-trading during choppy swings.
Four distinct bar-coloring modes—Reversal Solid, Reversal Fade, Exceeding Bands, Classic Heat—plus a “None” option, so traders can choose whether to highlight the latest signal, show signal age, emphasize breakout bars, or view a continuous heat gradient within the bands.
A semi-transparent fill between the EMA and the upper/lower bands that visually frames the statistical zone and makes extremes immediately obvious.
Concise “Up” and “Down” labels that plot exactly when price re-enters a band with confirming momentum, keeping chart clutter to a minimum.
A real-time, five-metric scoring table (z-score, RSI slope, price vs. EMA, trend state, re-entry) that updates every two bars, displaying individual +1/–1/0 scores and an averaged Buy/Sell/Neutral verdict for complete transparency.
Calculations
Compute the fair-value EMA over fairLen bars.
Subtract that EMA from current price each bar to derive the raw deviation.
Over zLen bars, calculate the rolling mean and standard deviation of those deviations.
Convert each deviation into a z-score by subtracting the mean and dividing by the standard deviation.
Plot the upper and lower bands at ±zThreshold × standard deviation around the EMA.
Calculate raw RSI over rsiLen bars, then smooth it with an EMA of length rsiEmaLen.
Derive the RSI slope by taking the difference between the current and previous smoothed RSI.
Detect a potential reentry when price exits one of the bands on the prior bar and re-enters on the current bar.
Require that reentry coincide with an RSI slope flip (positive for a lower-band reentry, negative for an upper-band reentry).
On first valid reentry per momentum swing, fire a buy or sell signal and set a memory flag; reset that flag only when the RSI slope crosses back through zero.
For each bar, assign scores of +1, –1, or 0 for the z-score direction, RSI slope, price vs. EMA, trend-state, and reentry status.
Average those five scores; if the result exceeds +0.1, label “Buy,” if below –0.1, label “Sell,” otherwise “Neutral.”
Update bar colors, the semi-transparent fill, reversal labels, and the scoring table every two bars to reflect the latest calculations.
How It Actually Works
On each new candle, the EMA baseline and band widths update to reflect current volatility. The RSI is smoothed and its slope recalculated. The script then looks back one bar to see if price exited either band and forward to see if it reentered. If that reentry coincides with an appropriate RSI slope flip—and no signal has yet been generated in that swing—a concise label appears. Bar colors refresh according to your selected mode, and the scoring table updates to show which of the five conditions passed or failed, along with the overall verdict. This process repeats seamlessly at each bar, giving traders a continuous feed of disciplined, statistically filtered reversal cues.
Inputs
All parameters are fully user-configurable, allowing you to tailor sensitivity, lookbacks, and visuals to your trading style:
EMA length (fairLen): number of bars for the fair-value EMA; higher values smooth more but lag further behind price.
Z-Score lookback (zLen): window for calculating the mean and standard deviation of price deviations; longer lookbacks reduce noise but respond more slowly to new volatility.
Z-Score threshold (zThreshold): number of standard deviations defining the upper and lower bands; common default is 2.0 for roughly the outer 5 percent of moves.
Source (src): choice of price series (close, hl2, etc.) used for EMA, deviation, and RSI calculations.
RSI length (rsiLen): period for raw RSI calculation; shorter values react faster to momentum changes but can be choppier.
RSI EMA length (rsiEmaLen): period for smoothing raw RSI before taking its slope; higher values filter more noise.
Bar coloring mode (colorMode): select from None, Reversal Solid, Reversal Fade, Exceeding Bands, or Classic Heat to control how bars are shaded in relation to signals and band positions.
Show signals (showSignals): toggle on-chart “Up” and “Down” labels for reversal entries.
Show scoring table (enableTable): toggle the display of the five-metric breakdown table.
Table position (tablePos): choose which corner (Top Left, Top Right, Bottom Left, Bottom Right) hosts the scoring table.
Conclusion
By merging a normalized z-score framework, momentum slope confirmation, disciplined signal memory, flexible visuals, and transparent scoring into one Pine Script overlay, Uptrick: Z-Trend Bands offers a powerful yet intuitive tool for intraday mean-reversion trading. Its adaptability to real-time volatility and multi-layered filter logic deliver clear, high-confidence reversal cues without the clutter or confusion of simpler indicators.
Disclaimer
This indicator is provided solely for educational and informational purposes. It does not constitute financial advice. Trading involves substantial risk and may not be suitable for all investors. Past performance is not indicative of future results. Always conduct your own testing and apply careful risk management before trading live.
VIX Z-Score (Inverted)📘 Indicator: VIX Z-Score (Inverted) + Table
🔍 Overview
This indicator calculates the Z-Score of the VIX (Volatility Index) and inverts it to identify potential buying opportunities during periods of fear and caution during periods of extreme optimism. The Z-Score is smoothed and visually displayed alongside a dynamic info table.
⚙️ How It Works
VIX Data: The VIX (ticker: CBOE:VIX) is pulled in real time.
Z-Score Calculation:
𝑍
=
(
𝑉
𝐼
𝑋
−
mean
)
standard deviation
Z=
standard deviation
(VIX−mean)
Over a customizable lookback period (default: 50).
Inversion:
Since high VIX usually means fear (often a contrarian buying signal), we invert the Z-Score:
𝑍
inv
=
−
𝑍
Z
inv
=−Z
Smoothing:
An EMA is applied to reduce noise and false signals.
Clamping:
The Z-Score is linearly scaled and capped between +2 and -2 for easy visualization in the info table.
📊 Z-Score Table (Top-Right)
Range Interpretation Table Color
+1.5 to +2 Extreme fear → Buy zone 🟩 Green
+0.5 to +1.5 Moderate fear 🟨 Lime
–0.5 to +0.5 Neutral ⬜ Gray
–0.5 to –1.5 Growing complacency 🟧 Orange
–1.5 to –2 Extreme optimism → Caution 🟥 Red
The current Z-Score (clamped version) is shown in real time on the right-hand info panel.
🧠 How to Use It
+2 Zone (Table: Green):
Market fear is at an extreme. Historically, such conditions are contrarian bullish—possible entry zones.
–2 Zone (Table: Red):
Indicates extreme optimism and low fear. Often a signal to be cautious or take profits.
Middle range (±0.5):
Market is neutral. Avoid major decisions based solely on sentiment here.
🧪 Best Practices
Combine with price action, volume, or trend filters.
Works well on daily or 4H timeframes.
Not a standalone signal—best used to confirm or fade sentiment extremes.
Comprehensive Volume and Metrics with Pre-Market Volume Data
This script is designed for traders who want a detailed view of market activity, including regular market and pre-market volume, dollar volume, relative volume (RVOL), average daily range (ADR), average true range (ATR), relative strength index (RSI), and the QQQ’s percentage change.
The script includes customizable metrics displayed in tables on the chart for easy analysis, with the option to toggle the visibility of each metric.
Key Features:
Volume and Dollar Volume:
Displays the volume of shares traded during the current day (or pre-market, if enabled).
Includes a calculation of dollar volume, representing the total dollar amount of trades (Volume × Close Price).
Relative Volume (RVOL):
Displays RVOL Day, which is the relative volume of the current day compared to the 2-day moving average.
Shows RVOL 90D, indicating relative volume over the past 90 days.
Both RVOL metrics are calculated as percentages and display the percentage change compared to the standard (100%).
Pre-Market Data:
Includes pre-market volume (PVOL) and pre-market dollar volume (P$ VOL) which are displayed only if pre-market data is enabled.
Tracks volume and dollar volume during pre-market hours (4:00 AM to 9:30 AM Eastern Time) for more in-depth analysis.
Optionally, shows pre-market RSI based on volume-weighted close prices.
Average Daily Range (ADR):
Displays the percentage change between the highest and lowest prices over the defined ADR period (default is 20 days).
Average True Range (ATR):
Shows the ATR, a popular volatility indicator, for a given period (default is 14 bars).
RSI (Relative Strength Index):
Displays RSI for the given period (default is 14).
RSI is calculated using pre-market data when available.
QQQ:
Shows the percentage change of the QQQ ETF from the previous day’s close.
The QQQ percentage change is color-coded: green for positive, red for negative, and gray for no change.
Customizable Inputs:
Visibility Options: Toggle the visibility of each metric, such as volume, dollar volume, RVOL, ADR, ATR, RSI, and QQQ.
Pre-Market Data: Enable or disable the display of pre-market data for volume and dollar volume.
Table Positioning: Adjust the position of tables displaying the metrics either at the bottom-left or bottom-right of the chart.
Text Color and Table Background: Choose between white or black text for the tables and customize the background color.
Tables:
The script utilizes tables to display multiple metrics in an organized and easy-to-read format.
The values are updated dynamically, reflecting real-time data as the market moves.
Pre-Market Data:
The script calculates pre-market volume and dollar volume, along with other key metrics like RSI and RVOL, to help assess market sentiment before the market officially opens.
The pre-market data is accumulated from 4:00 AM to 9:30 AM ET, allowing for pre-market analysis and comparison to regular market hours.
User-Friendly and Flexible:
This script is designed to be highly customizable, giving you the ability to toggle which metrics to display and where they appear on the chart. You can easily focus on the data that matters most to your trading strategy.
Z-Score Probability IndicatorThis is the Z-Score Probability indicator. As many people like my original Z-Score indicator and have expressed more interest in the powers of the Z, I decided to make this indicator which shows additional powers of the Z-Score.
Z-Score is not only useful for measuring a ticker or any other variable’s distance from the mean, it is also useful to calculate general probability in a normal distribution set. Not only can it calculate probability in a dataset, but it can also calculate the variables within said dataset by using the Standard Deviation and the Mean of the dataset.
Using these 2 aspects of the Z-Score, you can, In principle, have an indicator that operates similar to Fibonacci retracement levels with the added bonus of being able to actually ascertain the realistic probability of said retracement.
Let’s take a look at an example:
This is a chart showing SPY on the daily timeframe. If we look at the current Z-Score level, we can see that SPY is pushing into the 2 to 3 Z-Score range. We can see two things from this:
1. We can see that a retracement to a Z-Score of 2 would correspond to a price of 425.26 based on the current dataset. And
2. We can see that the probability that SPY retraces to a Z-Score of 2 is around 0.9800 or 98%.
To take it one step further, we can look at the various other variables in the distribution. If we were to bet on SPY retracing back to -1 SDs, that would correspond to a price of around 397.15, with a probability of around 0.1600 or 16% (see image below):
Let’s say, we thought SPY would go to $440. Well, we can see that the probability SPY goes to 434.64 currently is pretty low. How do we know? Because the Z-Score table shows us the probability of values falling BELOW that Z-score level in the current distribution. So if we look at this example below:
We can see that 0.9998 or roughly 99% of values in the current SPY distribution will fall below 434.64. Thus, it may be unrealistic, at this point in time, to target said value.
So what is a Z-Score Table?
Well, I need to disclose/clarify that the Z-Score Table being displayed in this indicator does Z-Score probability a HUGE injustice. However, with the constraints what is realistic to fit into an indicator, I had to make it far more succinct. Let’s take a look at an actual Z-Score Table below:
Above is a look an the actual Z-Score table. How it works is you first identify you’re Z-Score and then find the corresponding value that relates to your score. The number displayed in the dataset represents the number of variables in the dataset/density distribution that fall BELOW that particular Z-score.
So, for example, if we have a Z-Score of -2.31, we can consult that table, go to the -2.3 then scroll across to the 0.01 to represent -2.31. We would see that this Z-Score corresponds to a 0.0104 probability zone (or essentially 1%) indicating that the majority of the variables in the distribution fall below that mean Z-score. In terms of tickers and stocks, that would mean it would theoretically be “overbought”.
So what does the indicator Z-Table tell us?
I have averaged out the data for the purposes of this indicator. However, you can also reference a manual Z-Table to get the exact probability for the current precise Z-Score. However, the reality is it doesn’t necessarily matter to be exact when it comes to tickers. The reason being, ticker’s are in constant flux, and by the time you identify that probability, the ticker will already be at a different level. So generalizations are okay in these circumstances, you just need to get the “gist” of where the distribution lies.
So how do I use the indicator?
Using the indicator is pretty straightforward. Once launched, you will see the current Z-Score of the ticker, the current levels based on the distribution and the summarized Z-Table.
The Z-Table will turn gray to indicate the zone the ticker is currently in. In this case, we can see that SPY currently is in the 2 SD Zone, meaning that 0.98 or 98% of the current dataset being shown falls below the price we are at:
When we launch the settings, we can see a few inputs.
Lookback Length: This determines the number of candles back we want to calculate the distribution for. It is defaulted to 75, but you can adjust it to whichever length you want.
SMA Length: The SMA is optional but defaults to on. If you want to see the smoothed trend of the Z-Score, this will do the trick. It does not need to be set to the same
length as the Z-Score lookback. Thus, if you want a more or less responsive SMA with, say, a larger dataset, then you can reduce the SMA length yourself.
Distribution Probability Fills: This simply colour codes the distribution zones / probability zones on the indicator.
Show Z-Table: This will display the summarized Z-Table.
Show SMA: As I indicated, the SMA is optional, you can toggle it on or off to see the overall Z-Score trend.
Concluding Remarks:
And that my friends is the Z-Score Probability Indicator.
I hope you all enjoy it and find it helpful. As always leave your comments, questions and suggestions below.
Safe trades to all and take care!
Double Top/Bottom Screener - Today Only v2 //@version=6
indicator("Double Top/Bottom Screener - Today Only", overlay=true, max_lines_count=500)
// Inputs
leftBars = input.int(5, "Left Bars")
rightBars = input.int(5, "Right Bars")
tolerance = input.float(0.02, "Max Difference (e.g., 0.02 for 2 cents)", step=0.01)
atrLength = input.int(14, "ATR Length for Normalized Distance", minval=1)
requiredPeaks = input.int(3, "Required Identical Peaks", minval=2, maxval=5)
// Declarations of persistent variables and arrays
var array resistanceLevels = array.new(0)
var array resistanceCounts = array.new(0)
var array supportLevels = array.new(0)
var array supportCounts = array.new(0)
var array resLines = array.new(0)
var array supLines = array.new(0)
var bool hasDoubleTop = false
var bool hasDoubleBottom = false
var float doubleTopLevel = na
var float doubleBottomLevel = na
var int todayStart = na
// Step 1: Identify Swing Highs/Lows
swingHigh = ta.pivothigh(high, leftBars, rightBars)
swingLow = ta.pivotlow(low, leftBars, rightBars)
// Today's premarket start (04:00 AM ET)
todayStart := timestamp(syminfo.timezone, year, month, dayofmonth, 4, 0, 0)
// Clear arrays and delete lines on the first bar or new day
if barstate.isfirst or (dayofmonth != dayofmonth and time >= todayStart)
// Delete all existing lines only if arrays are not empty
if array.size(resLines) > 0
for i = array.size(resLines) - 1 to 0
line.delete(array.get(resLines, i))
if array.size(supLines) > 0
for i = array.size(supLines) - 1 to 0
line.delete(array.get(supLines, i))
// Clear arrays
array.clear(resistanceLevels)
array.clear(supportLevels)
array.clear(resistanceCounts)
array.clear(supportCounts)
array.clear(resLines)
array.clear(supLines)
// Reset flags
hasDoubleTop := false
hasDoubleBottom := false
doubleTopLevel := na
doubleBottomLevel := na
// Add new swings only if today and after premarket
if not na(swingHigh) and time >= todayStart and dayofmonth == dayofmonth
bool isEqualHigh = false
int peakIndex = -1
float prevLevel = na
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
prevLevel := array.get(resistanceLevels, i)
if math.abs(swingHigh - prevLevel) <= tolerance
isEqualHigh := true
peakIndex := i
break
if isEqualHigh and peakIndex >= 0
array.set(resistanceCounts, peakIndex, array.get(resistanceCounts, peakIndex) + 1)
if array.get(resistanceCounts, peakIndex) == requiredPeaks
hasDoubleTop := true
doubleTopLevel := prevLevel
else
array.push(resistanceLevels, swingHigh)
array.push(resistanceCounts, 1)
line newResLine = line.new(bar_index - rightBars, swingHigh, bar_index, swingHigh, color=color.red, width=2, extend=extend.none)
array.push(resLines, newResLine)
if not na(swingLow) and time >= todayStart and dayofmonth == dayofmonth
bool isEqualLow = false
int peakIndex = -1
float prevLevel = na
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
prevLevel := array.get(supportLevels, i)
if math.abs(swingLow - prevLevel) <= tolerance
isEqualLow := true
peakIndex := i
break
if isEqualLow and peakIndex >= 0
array.set(supportCounts, peakIndex, array.get(supportCounts, peakIndex) + 1)
if array.get(supportCounts, peakIndex) == requiredPeaks
hasDoubleBottom := true
doubleBottomLevel := prevLevel
else
array.push(supportLevels, swingLow)
array.push(supportCounts, 1)
line newSupLine = line.new(bar_index - rightBars, swingLow, bar_index, swingLow, color=color.green, width=2, extend=extend.none)
array.push(supLines, newSupLine)
// Monitor and remove broken levels/lines; reset pattern if the equal level breaks
if array.size(resistanceLevels) > 0
for i = array.size(resistanceLevels) - 1 to 0
float level = array.get(resistanceLevels, i)
if close > level
line.delete(array.get(resLines, i))
array.remove(resLines, i)
array.remove(resistanceLevels, i)
array.remove(resistanceCounts, i)
if level == doubleTopLevel
hasDoubleTop := false
doubleTopLevel := na
if array.size(supportLevels) > 0
for i = array.size(supportLevels) - 1 to 0
float level = array.get(supportLevels, i)
if close < level
line.delete(array.get(supLines, i))
array.remove(supLines, i)
array.remove(supportLevels, i)
array.remove(supportCounts, i)
if level == doubleBottomLevel
hasDoubleBottom := false
doubleBottomLevel := na
// Limit arrays (after removals)
if array.size(resistanceLevels) > 10
line oldLine = array.shift(resLines)
line.delete(oldLine)
array.shift(resistanceLevels)
array.shift(resistanceCounts)
if array.size(supportLevels) > 10
line oldLine = array.shift(supLines)
line.delete(oldLine)
array.shift(supportLevels)
array.shift(supportCounts)
// Pattern Signal: 1 only if the exact required number of peaks is met
patternSignal = (hasDoubleTop or hasDoubleBottom) ? 1 : 0
// New: Nearest Double Level Price
var float nearestDoubleLevel = na
if hasDoubleTop and not na(doubleTopLevel)
nearestDoubleLevel := doubleTopLevel
if hasDoubleBottom and not na(doubleBottomLevel)
nearestDoubleLevel := na(nearestDoubleLevel) ? doubleBottomLevel : (math.abs(close - doubleBottomLevel) < math.abs(close - nearestDoubleLevel) ? doubleBottomLevel : nearestDoubleLevel)
// New: Distance to Nearest Level (using ATR for normalization)
var float atr = ta.atr(atrLength)
var float distanceNormalizedATR = na
if not na(nearestDoubleLevel) and not na(atr) and atr > 0
distanceNormalizedATR := math.abs(close - nearestDoubleLevel) / atr
// Optional Bounce Signal (for reference)
bounceSignal = 0
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
float level = array.get(resistanceLevels, i)
if low <= level and high >= level and close < level
bounceSignal := 1
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
float level = array.get(supportLevels, i)
if high >= level and low <= level and close > level
bounceSignal := 1
// Outputs
plot(patternSignal, title="Pattern Signal", color=patternSignal == 1 ? color.purple : na, style=plot.style_circles)
plot(bounceSignal, title="Bounce Signal", color=bounceSignal == 1 ? color.yellow : na, style=plot.style_circles)
plot(nearestDoubleLevel, title="Nearest Double Level Price", color=color.orange)
plot(distanceNormalizedATR, title="Normalized Distance (ATR)", color=color.green)
bgcolor(patternSignal == 1 ? color.new(color.purple, 80) : na)
if patternSignal == 1 and barstate.isconfirmed
alert("Double Pattern detected on " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)
if barstate.islast
var table infoTable = table.new(position.top_right, 1, 4, bgcolor=color.new(color.black, 50))
table.cell(infoTable, 0, 0, "Pattern: " + str.tostring(patternSignal), bgcolor=patternSignal == 1 ? color.purple : color.gray)
table.cell(infoTable, 0, 1, "Bounce: " + str.tostring(bounceSignal), bgcolor=bounceSignal == 1 ? color.yellow : color.gray)
table.cell(infoTable, 0, 2, "Level: " + str.tostring(nearestDoubleLevel, "#.##"), bgcolor=color.orange)
table.cell(infoTable, 0, 3, "ATR Dist: " + str.tostring(distanceNormalizedATR, "#.##"), bgcolor=color.green)
Double Top/Bottom Screener - Today Only//@version=6
indicator("Double Top/Bottom Screener - Today Only", overlay=true, max_lines_count=500)
// Inputs
leftBars = input.int(5, "Left Bars")
rightBars = input.int(5, "Right Bars")
tolerance = input.float(0.02, "Max Difference (e.g., 0.02 for 2 cents)", step=0.01)
atrLength = input.int(14, "ATR Length for Normalized Distance", minval=1)
requiredPeaks = input.int(3, "Required Identical Peaks", minval=2, maxval=5)
// Declarations of persistent variables and arrays
var array resistanceLevels = array.new(0)
var array resistanceCounts = array.new(0)
var array supportLevels = array.new(0)
var array supportCounts = array.new(0)
var array resLines = array.new(0)
var array supLines = array.new(0)
var bool hasDoubleTop = false
var bool hasDoubleBottom = false
var float doubleTopLevel = na
var float doubleBottomLevel = na
var int todayStart = na
// Step 1: Identify Swing Highs/Lows
swingHigh = ta.pivothigh(high, leftBars, rightBars)
swingLow = ta.pivotlow(low, leftBars, rightBars)
// Today's premarket start (04:00 AM ET)
todayStart := timestamp(syminfo.timezone, year, month, dayofmonth, 4, 0, 0)
// Clear arrays and delete lines on the first bar or new day
if barstate.isfirst or (dayofmonth != dayofmonth and time >= todayStart)
// Delete all existing lines
for i = array.size(resLines) - 1 to 0
line.delete(array.get(resLines, i))
for i = array.size(supLines) - 1 to 0
line.delete(array.get(supLines, i))
// Clear arrays
array.clear(resistanceLevels)
array.clear(supportLevels)
array.clear(resistanceCounts)
array.clear(supportCounts)
array.clear(resLines)
array.clear(supLines)
// Reset flags
hasDoubleTop := false
hasDoubleBottom := false
doubleTopLevel := na
doubleBottomLevel := na
// Add new swings only if today and after premarket
if not na(swingHigh) and time >= todayStart and dayofmonth == dayofmonth
bool isEqualHigh = false
int peakIndex = -1
float prevLevel = na
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
prevLevel := array.get(resistanceLevels, i)
if math.abs(swingHigh - prevLevel) <= tolerance
isEqualHigh := true
peakIndex := i
break
if isEqualHigh and peakIndex >= 0
array.set(resistanceCounts, peakIndex, array.get(resistanceCounts, peakIndex) + 1)
if array.get(resistanceCounts, peakIndex) == requiredPeaks
hasDoubleTop := true
doubleTopLevel := prevLevel
else
array.push(resistanceLevels, swingHigh)
array.push(resistanceCounts, 1)
line newResLine = line.new(bar_index - rightBars, swingHigh, bar_index, swingHigh, color=color.red, width=2, extend=extend.none)
array.push(resLines, newResLine)
if not na(swingLow) and time >= todayStart and dayofmonth == dayofmonth
bool isEqualLow = false
int peakIndex = -1
float prevLevel = na
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
prevLevel := array.get(supportLevels, i)
if math.abs(swingLow - prevLevel) <= tolerance
isEqualLow := true
peakIndex := i
break
if isEqualLow and peakIndex >= 0
array.set(supportCounts, peakIndex, array.get(supportCounts, peakIndex) + 1)
if array.get(supportCounts, peakIndex) == requiredPeaks
hasDoubleBottom := true
doubleBottomLevel := prevLevel
else
array.push(supportLevels, swingLow)
array.push(supportCounts, 1)
line newSupLine = line.new(bar_index - rightBars, swingLow, bar_index, swingLow, color=color.green, width=2, extend=extend.none)
array.push(supLines, newSupLine)
// Monitor and remove broken levels/lines; reset pattern if the equal level breaks
if array.size(resistanceLevels) > 0
for i = array.size(resistanceLevels) - 1 to 0
float level = array.get(resistanceLevels, i)
if close > level
line.delete(array.get(resLines, i))
array.remove(resLines, i)
array.remove(resistanceLevels, i)
array.remove(resistanceCounts, i)
if level == doubleTopLevel
hasDoubleTop := false
doubleTopLevel := na
if array.size(supportLevels) > 0
for i = array.size(supportLevels) - 1 to 0
float level = array.get(supportLevels, i)
if close < level
line.delete(array.get(supLines, i))
array.remove(supLines, i)
array.remove(supportLevels, i)
array.remove(supportCounts, i)
if level == doubleBottomLevel
hasDoubleBottom := false
doubleBottomLevel := na
// Limit arrays (after removals)
if array.size(resistanceLevels) > 10
line oldLine = array.shift(resLines)
line.delete(oldLine)
array.shift(resistanceLevels)
array.shift(resistanceCounts)
if array.size(supportLevels) > 10
line oldLine = array.shift(supLines)
line.delete(oldLine)
array.shift(supportLevels)
array.shift(supportCounts)
// Pattern Signal: 1 only if the exact required number of peaks is met
patternSignal = (hasDoubleTop or hasDoubleBottom) ? 1 : 0
// New: Nearest Double Level Price
var float nearestDoubleLevel = na
if hasDoubleTop and not na(doubleTopLevel)
nearestDoubleLevel := doubleTopLevel
if hasDoubleBottom and not na(doubleBottomLevel)
nearestDoubleLevel := na(nearestDoubleLevel) ? doubleBottomLevel : (math.abs(close - doubleBottomLevel) < math.abs(close - nearestDoubleLevel) ? doubleBottomLevel : nearestDoubleLevel)
// New: Distance to Nearest Level (using ATR for normalization)
var float atr = ta.atr(atrLength)
var float distanceNormalizedATR = na
if not na(nearestDoubleLevel) and not na(atr) and atr > 0
distanceNormalizedATR := math.abs(close - nearestDoubleLevel) / atr
// Optional Bounce Signal (for reference)
bounceSignal = 0
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
float level = array.get(resistanceLevels, i)
if low <= level and high >= level and close < level
bounceSignal := 1
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
float level = array.get(supportLevels, i)
if high >= level and low <= level and close > level
bounceSignal := 1
// Outputs
plot(patternSignal, title="Pattern Signal", color=patternSignal == 1 ? color.purple : na, style=plot.style_circles)
plot(bounceSignal, title="Bounce Signal", color=bounceSignal == 1 ? color.yellow : na, style=plot.style_circles)
plot(nearestDoubleLevel, title="Nearest Double Level Price", color=color.orange)
plot(distanceNormalizedATR, title="Normalized Distance (ATR)", color=color.green)
bgcolor(patternSignal == 1 ? color.new(color.purple, 80) : na)
if patternSignal == 1 and barstate.isconfirmed
alert("Double Pattern detected on " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)
if barstate.islast
var table infoTable = table.new(position.top_right, 1, 4, bgcolor=color.new(color.black, 50))
table.cell(infoTable, 0, 0, "Pattern: " + str.tostring(patternSignal), bgcolor=patternSignal == 1 ? color.purple : color.gray)
table.cell(infoTable, 0, 1, "Bounce: " + str.tostring(bounceSignal), bgcolor=bounceSignal == 1 ? color.yellow : color.gray)
table.cell(infoTable, 0, 2, "Level: " + str.tostring(nearestDoubleLevel, "#.##"), bgcolor=color.orange)
table.cell(infoTable, 0, 3, "ATR Dist: " + str.tostring(distanceNormalizedATR, "#.##"), bgcolor=color.green)
Double Top/Bottom Screener V1//@version=6
indicator("Double Top/Bottom Screener", overlay=true, max_lines_count=500)
// Inputs
leftBars = input.int(5, "Left Bars")
rightBars = input.int(5, "Right Bars")
tolerance = input.float(0.02, "Max Difference (e.g., 0.02 for 2 cents)", step=0.01)
atrLength = input.int(14, "ATR Length for Normalized Distance", minval=1)
requiredPeaks = input.int(3, "Required Identical Peaks", minval=2, maxval=5)
// Declarations of persistent variables and arrays
var array resistanceLevels = array.new(0)
var array resistanceCounts = array.new(0)
var array supportLevels = array.new(0)
var array supportCounts = array.new(0)
var array resLines = array.new(0)
var array supLines = array.new(0)
var bool hasDoubleTop = false
var bool hasDoubleBottom = false
var float doubleTopLevel = na
var float doubleBottomLevel = na
var int todayStart = na
var bool isNewDay = false
// Step 1: Identify Swing Highs/Lows
swingHigh = ta.pivothigh(high, leftBars, rightBars)
swingLow = ta.pivotlow(low, leftBars, rightBars)
// Today's premarket start (04:00 AM ET)
if dayofmonth != dayofmonth
todayStart := timestamp(syminfo.timezone, year, month, dayofmonth, 4, 0, 0)
isNewDay := true
else
isNewDay := false
// Clear arrays and reset flags only once at premarket start
if isNewDay and time >= todayStart
array.clear(resistanceLevels)
array.clear(supportLevels)
array.clear(resistanceCounts)
array.clear(supportCounts)
array.clear(resLines)
array.clear(supLines)
hasDoubleTop := false
hasDoubleBottom := false
doubleTopLevel := na
doubleBottomLevel := na
// Add new swings and check for identical peaks
if not na(swingHigh) and time >= todayStart
bool isEqualHigh = false
int peakIndex = -1
float prevLevel = na
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
prevLevel := array.get(resistanceLevels, i)
if math.abs(swingHigh - prevLevel) <= tolerance
isEqualHigh := true
peakIndex := i
break
if isEqualHigh and peakIndex >= 0
array.set(resistanceCounts, peakIndex, array.get(resistanceCounts, peakIndex) + 1)
if array.get(resistanceCounts, peakIndex) == requiredPeaks
hasDoubleTop := true
doubleTopLevel := prevLevel
else
array.push(resistanceLevels, swingHigh)
array.push(resistanceCounts, 1)
line newResLine = line.new(bar_index - rightBars, swingHigh, bar_index, swingHigh, color=color.red, width=2, extend=extend.right)
array.push(resLines, newResLine)
if not na(swingLow) and time >= todayStart
bool isEqualLow = false
int peakIndex = -1
float prevLevel = na
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
prevLevel := array.get(supportLevels, i)
if math.abs(swingLow - prevLevel) <= tolerance
isEqualLow := true
peakIndex := i
break
if isEqualLow and peakIndex >= 0
array.set(supportCounts, peakIndex, array.get(supportCounts, peakIndex) + 1)
if array.get(supportCounts, peakIndex) == requiredPeaks
hasDoubleBottom := true
doubleBottomLevel := prevLevel
else
array.push(supportLevels, swingLow)
array.push(supportCounts, 1)
line newSupLine = line.new(bar_index - rightBars, swingLow, bar_index, swingLow, color=color.green, width=2, extend=extend.right)
array.push(supLines, newSupLine)
// Monitor and remove broken levels/lines; reset pattern if the equal level breaks
if array.size(resistanceLevels) > 0
for i = array.size(resistanceLevels) - 1 to 0
float level = array.get(resistanceLevels, i)
if close > level
line.delete(array.get(resLines, i))
array.remove(resLines, i)
array.remove(resistanceLevels, i)
array.remove(resistanceCounts, i)
if level == doubleTopLevel
hasDoubleTop := false
doubleTopLevel := na
if array.size(supportLevels) > 0
for i = array.size(supportLevels) - 1 to 0
float level = array.get(supportLevels, i)
if close < level
line.delete(array.get(supLines, i))
array.remove(supLines, i)
array.remove(supportLevels, i)
array.remove(supportCounts, i)
if level == doubleBottomLevel
hasDoubleBottom := false
doubleBottomLevel := na
// Limit arrays (after removals)
if array.size(resistanceLevels) > 10
line oldLine = array.shift(resLines)
line.delete(oldLine)
array.shift(resistanceLevels)
array.shift(resistanceCounts)
if array.size(supportLevels) > 10
line oldLine = array.shift(supLines)
line.delete(oldLine)
array.shift(supportLevels)
array.shift(supportCounts)
// Pattern Signal: 1 only if the exact required number of peaks is met
patternSignal = (hasDoubleTop or hasDoubleBottom) and (array.size(resistanceCounts) > 0 and array.get(resistanceCounts, array.size(resistanceCounts) - 1) == requiredPeaks or array.size(supportCounts) > 0 and array.get(supportCounts, array.size(supportCounts) - 1) == requiredPeaks) ? 1 : 0
// New: Nearest Double Level Price
var float nearestDoubleLevel = na
if hasDoubleTop and not na(doubleTopLevel)
nearestDoubleLevel := doubleTopLevel
if hasDoubleBottom and not na(doubleBottomLevel)
nearestDoubleLevel := na(nearestDoubleLevel) ? doubleBottomLevel : (math.abs(close - doubleBottomLevel) < math.abs(close - nearestDoubleLevel) ? doubleBottomLevel : nearestDoubleLevel)
// New: Distance to Nearest Level (using ATR for normalization)
var float atr = ta.atr(atrLength)
var float distanceNormalizedATR = na
if not na(nearestDoubleLevel) and not na(atr) and atr > 0
distanceNormalizedATR := math.abs(close - nearestDoubleLevel) / atr
// Optional Bounce Signal (for reference)
bounceSignal = 0
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
float level = array.get(resistanceLevels, i)
if low <= level and high >= level and close < level
bounceSignal := 1
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
float level = array.get(supportLevels, i)
if high >= level and low <= level and close > level
bounceSignal := 1
// Outputs
plot(patternSignal, title="Pattern Signal", color=patternSignal == 1 ? color.purple : na, style=plot.style_circles)
plot(bounceSignal, title="Bounce Signal", color=bounceSignal == 1 ? color.yellow : na, style=plot.style_circles)
plot(nearestDoubleLevel, title="Nearest Double Level Price", color=color.orange)
plot(distanceNormalizedATR, title="Normalized Distance (ATR)", color=color.green)
bgcolor(patternSignal == 1 ? color.new(color.purple, 80) : na)
if patternSignal == 1 and barstate.isconfirmed
alert("Double Pattern detected on " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)
if barstate.islast
var table infoTable = table.new(position.top_right, 1, 4, bgcolor=color.new(color.black, 50))
table.cell(infoTable, 0, 0, "Pattern: " + str.tostring(patternSignal), bgcolor=patternSignal == 1 ? color.purple : color.gray)
table.cell(infoTable, 0, 1, "Bounce: " + str.tostring(bounceSignal), bgcolor=bounceSignal == 1 ? color.yellow : color.gray)
table.cell(infoTable, 0, 2, "Level: " + str.tostring(nearestDoubleLevel, "#.##"), bgcolor=color.orange)
table.cell(infoTable, 0, 3, "ATR Dist: " + str.tostring(distanceNormalizedATR, "#.##"), bgcolor=color.green)
Double Top/Bottom Screener 3-5 peaks //@version=6
indicator("Double Top/Bottom Screener", overlay=true, max_lines_count=500)
// Inputs
leftBars = input.int(5, "Left Bars")
rightBars = input.int(5, "Right Bars")
tolerance = input.float(0.02, "Max Difference (e.g., 0.02 for 2 cents)", step=0.01)
atrLength = input.int(14, "ATR Length for Normalized Distance", minval=1)
maxPeaks = input.int(5, "Max Identical Peaks", minval=2, maxval=5)
// Declarations of persistent variables and arrays
var array resistanceLevels = array.new(0)
var array resistanceCounts = array.new(0)
var array supportLevels = array.new(0)
var array supportCounts = array.new(0)
var array resLines = array.new(0)
var array supLines = array.new(0)
var bool hasDoubleTop = false
var bool hasDoubleBottom = false
var float doubleTopLevel = na
var float doubleBottomLevel = na
var int todayStart = na
var bool isNewDay = false
// Step 1: Identify Swing Highs/Lows
swingHigh = ta.pivothigh(high, leftBars, rightBars)
swingLow = ta.pivotlow(low, leftBars, rightBars)
// Today's premarket start (04:00 AM ET)
if dayofmonth != dayofmonth
todayStart := timestamp(syminfo.timezone, year, month, dayofmonth, 4, 0, 0)
isNewDay := true
else
isNewDay := false
// Clear arrays and reset flags only once at premarket start
if isNewDay and time >= todayStart
array.clear(resistanceLevels)
array.clear(supportLevels)
array.clear(resistanceCounts)
array.clear(supportCounts)
array.clear(resLines)
array.clear(supLines)
hasDoubleTop := false
hasDoubleBottom := false
doubleTopLevel := na
doubleBottomLevel := na
// Add new swings and check for identical peaks
if not na(swingHigh) and time >= todayStart
bool isEqualHigh = false
int peakIndex = -1
float prevLevel = na // Declare prevLevel with initial value
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
prevLevel := array.get(resistanceLevels, i)
if math.abs(swingHigh - prevLevel) <= tolerance
isEqualHigh := true
peakIndex := i
break
if isEqualHigh and peakIndex >= 0
array.set(resistanceCounts, peakIndex, array.get(resistanceCounts, peakIndex) + 1)
if array.get(resistanceCounts, peakIndex) >= maxPeaks
hasDoubleTop := true
doubleTopLevel := prevLevel
else
array.push(resistanceLevels, swingHigh)
array.push(resistanceCounts, 1)
line newResLine = line.new(bar_index - rightBars, swingHigh, bar_index, swingHigh, color=color.red, width=2, extend=extend.right)
array.push(resLines, newResLine)
if not na(swingLow) and time >= todayStart
bool isEqualLow = false
int peakIndex = -1
float prevLevel = na // Declare prevLevel with initial value
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
prevLevel := array.get(supportLevels, i)
if math.abs(swingLow - prevLevel) <= tolerance
isEqualLow := true
peakIndex := i
break
if isEqualLow and peakIndex >= 0
array.set(supportCounts, peakIndex, array.get(supportCounts, peakIndex) + 1)
if array.get(supportCounts, peakIndex) >= maxPeaks
hasDoubleBottom := true
doubleBottomLevel := prevLevel
else
array.push(supportLevels, swingLow)
array.push(supportCounts, 1)
line newSupLine = line.new(bar_index - rightBars, swingLow, bar_index, swingLow, color=color.green, width=2, extend=extend.right)
array.push(supLines, newSupLine)
// Monitor and remove broken levels/lines; reset pattern if the equal level breaks
if array.size(resistanceLevels) > 0
for i = array.size(resistanceLevels) - 1 to 0
float level = array.get(resistanceLevels, i)
if close > level
line.delete(array.get(resLines, i))
array.remove(resLines, i)
array.remove(resistanceLevels, i)
array.remove(resistanceCounts, i)
if level == doubleTopLevel
hasDoubleTop := false
doubleTopLevel := na
if array.size(supportLevels) > 0
for i = array.size(supportLevels) - 1 to 0
float level = array.get(supportLevels, i)
if close < level
line.delete(array.get(supLines, i))
array.remove(supLines, i)
array.remove(supportLevels, i)
array.remove(supportCounts, i)
if level == doubleBottomLevel
hasDoubleBottom := false
doubleBottomLevel := na
// Limit arrays (after removals)
if array.size(resistanceLevels) > 10
line oldLine = array.shift(resLines)
line.delete(oldLine)
array.shift(resistanceLevels)
array.shift(resistanceCounts)
if array.size(supportLevels) > 10
line oldLine = array.shift(supLines)
line.delete(oldLine)
array.shift(supportLevels)
array.shift(supportCounts)
// Pattern Signal: 1 if any pattern with maxPeaks is active and unbroken
patternSignal = (hasDoubleTop or hasDoubleBottom) ? 1 : 0
// New: Nearest Double Level Price
var float nearestDoubleLevel = na
if hasDoubleTop and not na(doubleTopLevel)
nearestDoubleLevel := doubleTopLevel
if hasDoubleBottom and not na(doubleBottomLevel)
nearestDoubleLevel := na(nearestDoubleLevel) ? doubleBottomLevel : (math.abs(close - doubleBottomLevel) < math.abs(close - nearestDoubleLevel) ? doubleBottomLevel : nearestDoubleLevel)
// New: Distance to Nearest Level (using ATR for normalization)
var float atr = ta.atr(atrLength)
var float distanceNormalizedATR = na
if not na(nearestDoubleLevel) and not na(atr) and atr > 0
distanceNormalizedATR := math.abs(close - nearestDoubleLevel) / atr
// Optional Bounce Signal (for reference)
bounceSignal = 0
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
float level = array.get(resistanceLevels, i)
if low <= level and high >= level and close < level
bounceSignal := 1
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
float level = array.get(supportLevels, i)
if high >= level and low <= level and close > level
bounceSignal := 1
// Outputs
plot(patternSignal, title="Pattern Signal", color=patternSignal == 1 ? color.purple : na, style=plot.style_circles)
plot(bounceSignal, title="Bounce Signal", color=bounceSignal == 1 ? color.yellow : na, style=plot.style_circles)
plot(nearestDoubleLevel, title="Nearest Double Level Price", color=color.orange)
plot(distanceNormalizedATR, title="Normalized Distance (ATR)", color=color.green)
bgcolor(patternSignal == 1 ? color.new(color.purple, 80) : na)
if patternSignal == 1 and barstate.isconfirmed
alert("Double Pattern detected on " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)
if barstate.islast
var table infoTable = table.new(position.top_right, 1, 4, bgcolor=color.new(color.black, 50))
table.cell(infoTable, 0, 0, "Pattern: " + str.tostring(patternSignal), bgcolor=patternSignal == 1 ? color.purple : color.gray)
table.cell(infoTable, 0, 1, "Bounce: " + str.tostring(bounceSignal), bgcolor=bounceSignal == 1 ? color.yellow : color.gray)
table.cell(infoTable, 0, 2, "Level: " + str.tostring(nearestDoubleLevel, "#.##"), bgcolor=color.orange)
table.cell(infoTable, 0, 3, "ATR Dist: " + str.tostring(distanceNormalizedATR, "#.##"), bgcolor=color.green)
iD EMARSI on ChartSCRIPT OVERVIEW
The EMARSI indicator is an advanced technical analysis tool that maps RSI values directly onto price charts. With adaptive scaling capabilities, it provides a unique visualization of momentum that flows naturally with price action, making it particularly valuable for FOREX and low-priced securities trading.
KEY FEATURES
1 PRICE MAPPED RSI VISUALIZATION
Unlike traditional RSI that displays in a separate window, EMARSI plots the RSI directly on the price chart, creating a flowing line that identifies momentum shifts within the context of price action:
// Map RSI to price chart with better scaling
mappedRsi = useAdaptiveScaling ?
median + ((rsi - 50) / 50 * (pQH - pQL) / 2 * math.min(1.0, 1/scalingFactor)) :
down == pQL ? pQH : up == pQL ? pQL : median - (median / (1 + up / down))
2 ADAPTIVE SCALING SYSTEM
The script features an intelligent scaling system that automatically adjusts to different market conditions and price levels:
// Calculate adaptive scaling factor based on selected method
scalingFactor = if scalingMethod == "ATR-Based"
math.min(maxScalingFactor, math.max(1.0, minTickSize / (atrValue/avgPrice)))
else if scalingMethod == "Price-Based"
math.min(maxScalingFactor, math.max(1.0, math.sqrt(100 / math.max(avgPrice, 0.01))))
else // Volume-Based
math.min(maxScalingFactor, math.max(1.0, math.sqrt(1000000 / math.max(volume, 100))))
3 MODIFIED RSI CALCULATION
EMARSI uses a specially formulated RSI calculation that works with an adaptive base value to maintain consistency across different price ranges:
// Adaptive RSI Base based on price levels to improve flow
adaptiveRsiBase = useAdaptiveScaling ? rsiBase * scalingFactor : rsiBase
// Calculate RSI components with adaptivity
up = ta.rma(math.max(ta.change(rsiSourceInput), adaptiveRsiBase), emaSlowLength)
down = ta.rma(-math.min(ta.change(rsiSourceInput), adaptiveRsiBase), rsiLengthInput)
// Improved RSI calculation with value constraint
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
4 MOVING AVERAGE CROSSOVER SYSTEM
The indicator creates a smooth moving average of the RSI line, enabling a crossover system that generates trading signals:
// Calculate MA of mapped RSI
rsiMA = ma(mappedRsi, emaSlowLength, maTypeInput)
// Strategy entries
if ta.crossover(mappedRsi, rsiMA)
strategy.entry("RSI Long", strategy.long)
if ta.crossunder(mappedRsi, rsiMA)
strategy.entry("RSI Short", strategy.short)
5 VISUAL REFERENCE FRAMEWORK
The script includes visual guides that help interpret the RSI movement within the context of recent price action:
// Calculate pivot high and low
pQH = ta.highest(high, hlLen)
pQL = ta.lowest(low, hlLen)
median = (pQH + pQL) / 2
// Plotting
plot(pQH, "Pivot High", color=color.rgb(82, 228, 102, 90))
plot(pQL, "Pivot Low", color=color.rgb(231, 65, 65, 90))
med = plot(median, style=plot.style_steplinebr, linewidth=1, color=color.rgb(238, 101, 59, 90))
6 DYNAMIC COLOR SYSTEM
The indicator uses color fills to clearly visualize the relationship between the RSI and its moving average:
// Color fills based on RSI vs MA
colUp = mappedRsi > rsiMA ? input.color(color.rgb(128, 255, 0), '', group= 'RSI > EMA', inline= 'up') :
input.color(color.rgb(240, 9, 9, 95), '', group= 'RSI < EMA', inline= 'dn')
colDn = mappedRsi > rsiMA ? input.color(color.rgb(0, 230, 35, 95), '', group= 'RSI > EMA', inline= 'up') :
input.color(color.rgb(255, 47, 0), '', group= 'RSI < EMA', inline= 'dn')
fill(rsiPlot, emarsi, mappedRsi > rsiMA ? pQH : rsiMA, mappedRsi > rsiMA ? rsiMA : pQL, colUp, colDn)
7 REAL TIME PARAMETER MONITORING
A transparent information panel provides real-time feedback on the adaptive parameters being applied:
// Information display
var table infoPanel = table.new(position.top_right, 2, 3, bgcolor=color.rgb(0, 0, 0, 80))
if barstate.islast
table.cell(infoPanel, 0, 0, "Current Scaling Factor", text_color=color.white)
table.cell(infoPanel, 1, 0, str.tostring(scalingFactor, "#.###"), text_color=color.white)
table.cell(infoPanel, 0, 1, "Adaptive RSI Base", text_color=color.white)
table.cell(infoPanel, 1, 1, str.tostring(adaptiveRsiBase, "#.####"), text_color=color.white)
BENEFITS FOR TRADERS
INTUITIVE MOMENTUM VISUALIZATION
By mapping RSI directly onto the price chart, traders can immediately see the relationship between momentum and price without switching between different indicator windows.
ADAPTIVE TO ANY MARKET CONDITION
The three scaling methods (ATR-Based, Price-Based, and Volume-Based) ensure the indicator performs consistently across different market conditions, volatility regimes, and price levels.
PREVENTS EXTREME VALUES
The adaptive scaling system prevents the RSI from generating extreme values that exceed chart boundaries when trading low-priced securities or during high volatility periods.
CLEAR TRADING SIGNALS
The RSI and moving average crossover system provides clear entry signals that are visually reinforced through color changes, making it easy to identify potential trading opportunities.
SUITABLE FOR MULTIPLE TIMEFRAMES
The indicator works effectively across multiple timeframes, from intraday to daily charts, making it versatile for different trading styles and strategies.
TRANSPARENT PARAMETER ADJUSTMENT
The information panel provides real-time feedback on how the adaptive system is adjusting to current market conditions, helping traders understand why the indicator is behaving as it is.
CUSTOMIZABLE VISUALIZATION
Multiple visualization options including Bollinger Bands, different moving average types, and customizable colors allow traders to adapt the indicator to their personal preferences.
CONCLUSION
The EMARSI indicator represents a significant advancement in RSI visualization by directly mapping momentum onto price charts with adaptive scaling. This approach makes momentum shifts more intuitive to identify and helps prevent the scaling issues that commonly affect RSI-based indicators when applied to low-priced securities or volatile markets.
MTF Volume Flow IndicatorThe MTF Volume Flow Indicator (MTF VFI) is an advanced and versatile tool that enhances market analysis by tracking the flow of volume across multiple timeframes. By integrating volume flow with multi-timeframe analysis, this indicator provides traders with a comprehensive understanding of market trends, momentum, and potential reversals.
Key Features
Multi-Timeframe Volume Flow Analysis: The MTF VFI computes the Volume Flow Indicator across various timeframes, ranging from 1 minute to 1 month. This multi-timeframe analysis enables traders to observe and compare volume flow dynamics across different time horizons, offering deeper insights into market behavior.
Customizable VFI Settings: The indicator includes configurable VFI parameters such as length, coefficient, and volume cutoff, allowing users to tailor the analysis to different market conditions and trading strategies. This flexibility ensures that the indicator remains relevant across diverse market environments.
Signal Line and Delta Calculations: The script features a signal line derived from the VFI and calculates the delta values (the difference between VFI and the signal line). These delta values are essential for identifying potential buy or sell signals and are presented as histograms for easy visual interpretation.
Cumulative Delta with Dynamic Bands: The indicator introduces cumulative delta, a powerful tool that combines average and median VFI values to provide a clearer picture of market sentiment. Two standard deviation bands are plotted around the cumulative delta, offering a range within which price movements are likely to remain. These bands are smoothed using a 21-period EMA, providing a more refined view of market volatility.
Multi-Timeframe and Analysis Tables: The MTF VFI includes optional tables that display VFI, signal line, and delta values across all selected timeframes. Additionally, an analysis table presents key statistical metrics such as the highest, lowest, average, standard deviation, range, and median VFI values. These tables provide a concise summary of market conditions, aiding in strategic decision-making.
Dynamic Display Options: The indicator offers extensive customization options, allowing traders to display or hide elements such as delta histograms, delta bands, and tables. This ensures that users can focus on the most relevant information for their trading strategy.
Neutral Candle Coloring Option: Traders can enable neutral candle colors, where bearish candles are gray and bullish candles are white. This feature helps to reduce noise and maintain focus on the overall trend and volume flow analysis.
How It Works
Volume Flow Indicator Calculation: The VFI is calculated using a combination of typical price, volume, and the standard deviation of price changes. The indicator smooths the VFI based on user preferences, allowing traders to adjust the sensitivity of the analysis to better match their trading style.
Multi-Timeframe Integration: The script pulls VFI calculations from multiple timeframes, providing a holistic view of market trends. By analyzing VFI across different timeframes, traders can detect alignments or divergences in volume flow that might indicate trend strength or weakness.
Cumulative Delta and Dynamic Bands: The cumulative delta is computed by combining the average and median VFI values. Dynamic two-standard-deviation bands are plotted around this cumulative delta, providing upper and lower bounds for expected price movements. These bands are further smoothed with a 21-period EMA, enhancing their effectiveness in volatile markets.
Delta Analysis and Histogram Display: The difference between the VFI and its signal line (delta) is calculated and displayed as histograms. This visual representation helps traders quickly assess momentum and identify potential reversals or trend continuations. The cumulative delta is color-coded dynamically based on its direction, adding an extra layer of visual clarity.
Alerts
VFI Crossover Alerts: The indicator includes customizable alerts that notify traders when the VFI crosses above or below its signal line. These alerts are crucial for catching potential trend reversals or continuation signals, even when the trader is not actively monitoring the chart.
Customizable Alert Conditions: Traders can tailor alert conditions to their preferred timeframes and VFI settings, ensuring that the notifications they receive are relevant and timely for their specific trading strategies.
Application
Trend Identification and Confirmation: The MTF VFI aids in identifying and confirming trends by analyzing volume flow across multiple timeframes. This capability is particularly useful for detecting trends that may not be visible on a single timeframe.
Momentum and Divergence Analysis: By comparing VFI and delta values across timeframes, and analyzing cumulative delta with dynamic bands, traders can gain insights into market momentum and potential divergences, which are often precursors to reversals.
Strategic Decision-Making: With its comprehensive multi-timeframe analysis, cumulative delta, and statistical summaries, the MTF VFI equips traders with the information needed to make informed trading decisions, whether for short-term trades or long-term investments.
Visual Clarity and Customization: The indicator’s dynamic display options and neutral candle coloring help traders maintain a clear and focused view of the market, customizing the visualization to match their specific needs.
The MTF Volume Flow Indicator (MTF VFI) by CryptoSea is an essential tool for traders who seek to gain a deeper understanding of market trends and volume dynamics across multiple timeframes. Its advanced features and customization options make it a valuable addition to any trader’s toolkit.
Bias AnalyzerName: Bias Analyzer
Category: Market Analyzer
Timeframe: 1H and 1D, depending on the Analysis type.
Technical Analysis: Usually when we think about a Trading System we start from an idea. This idea comes normally from observation and the study of the market.
Have we ever observed a market - for example Bitcoin - and thought that it increases at the start of a USA session? Great, this is a well-known category of Trading System and the purpose of the Bias Analyzer is to study these phenomena.
There are different types of Trading System that we can classify considering the market in-efficiency that we use to our advantage. In this case we make the Bias. Literally "inclination" or "presupposition" or precisely "tendency" of the price to go up or down in a temporal way.
The characteristics of the Bias depend on how much the Bias is persistent on the market since the analysed period. therefore we can consider:
Hourly Bias : analysing the hourly behaviours during the week. Trades normally last from a few hours to a few days.
Seasonal Bias : analysing the behaviour of the weeks in the monthly or annual context, evaluating the seasons.
Suggested usage: The possibilities of the tool are infinite, these are some scenarios of use:
Development of Intraday Trading Systems based on Hourly Bias with possible filters for specific days of the week.
Development of a Multi-day Trading System based on daily Bias with monthly analysis.
To identify the best day to execute our investment through Dollar Cost Average with a bit of healthy buy the dip
Main features:
Hourly Summary organized in Week
The cells contain the sum of the various price deltas for the single hour. The transparency indicates the frequency in which the candles close positive or negative. This information is available both in a synthetic way, as in the first column "Sum", and for each day of the week.
Hourly Details organized in different entry/exit
Shows the cumulative data of the various deltas, considering the purchase and the sale at certain times. In the rows are represented the buying hours and in the columns the selling hours.
Daily Summary organized in Months
The cells contain the summation of the various price deltas for the single day.
Hourly Details organized in different entry/exit
Allows to visualise the detailed analysis table, choosing to do it for all the months or for a specific month and shows the cumulative data of the various deltas, considering the purchase and the sale in certain days.
Configuration: You can configure the tool easily and completely.
Analysis
Calculate from Close to Open : this is the core of the whole analysis where the "Price Delta" to be calculated is defined. At this moment there is the possibility to calculate the distance between opening and closing.
Calculate in Percent or Cash : this allows to calculate the Price Delta in Percent or in Cash.
Analysis on 1H Timeframe
Show Hourly Summary on : allows to visualise the summary analysis table of the week. The cells contain the sum of the various price deltas for the single hour. The transparency indicates the frequency in which the candles close positive or negative. This information is available both in a synthetic way, as in the first column "Sum", and for each day of the week. At the bottom left there is also data which allows us to understand how many candles are being analysed. At the bottom of each day it is possible to visualise the cumulative data of the day. The position of the table is customizable.
Show Hourly Details of on : allows to visualise the detailed analysis table, choosing to do it for all days or for a specific day, and shows the cumulative data of the various deltas, considering the purchase and the sale at certain times. In the rows are represented the buying hours and in the columns the selling hours. For example, going to the table "All Days" we can see in the cell of row 13 and in column 22 the cumulative data of a possible buy on 13 and a sell at the end of 22. To facilitate the research of the values there is a configurable transparency system.
Analysis on 1D Timeframe
Show Daily Summary on : allows to visualise the summary analysis table of the month. The cells contain the summation of the various price deltas for the single day: The first row is the summation of all days of the month for all months in the analysis period, while the other rows represent the analysis for the various days of the individual months.
Show Daily Details of on : allows to visualise the detailed analysis table, choosing to do it for all the months or for a specific month and shows the cumulative data of the various deltas, considering the purchase and the sale in certain days. In the rows are represented the buying days and in the columns the selling days. For example, going to the table "All Months" we can see in the cell at row 1 and at column 3 the cumulative of a possible purchase on the 1st and the sale on the 3rd. To facilitate the research of the values, there is a configurable transparency system.
Table Layout
Size : allows to define the size of the text in the table.
Precision : it is possible to define the decimal precision of the calculations presented in the tables.
Transparency Factor : allows the application of a multiplication factor when the table calculates the transparency of detail tables.
Colours : allows to specify the colours of Profit, Loss and Neutral, besides to adapt a style coherent with the Dark Mode or Light Mode of Trading View
Volatility Filter
It is possible to directly apply a filter to the time series on which the delta is calculated. The volatility filter uses the ATR - an indicator that allows you to calculate the volatility in a given period. Briefly: the higher the ATR value, the higher the volatility. Therefore the filter works by comparing the volatility on two periods and indicates compression or expansion.
Backtest Dates
In order to facilitate the identification of in-sample and out-of-sample data, as well as the degradation of a given behaviour, it is possible to specify a period in which to do the analysis.
Double Top/Bottom Screener - Today Only V4//@version=6
indicator("Double Top/Bottom Screener - Today Only", overlay=true, max_lines_count=500)
// Inputs
leftBars = input.int(5, "Left Bars")
rightBars = input.int(5, "Right Bars")
tolerance = input.float(0.02, "Max Difference (e.g., 0.02 for 2 cents)", step=0.01)
atrLength = input.int(14, "ATR Length for Normalized Distance", minval=1)
requiredPeaks = input.int(3, "Required Identical Peaks", minval=2, maxval=5)
// Declarations of persistent variables and arrays
var array resistanceLevels = array.new(0)
var array resistanceCounts = array.new(0)
var array supportLevels = array.new(0)
var array supportCounts = array.new(0)
var array resLines = array.new(0)
var array supLines = array.new(0)
var bool hasDoubleTop = false
var bool hasDoubleBottom = false
var float doubleTopLevel = na
var float doubleBottomLevel = na
var int todayStart = na
var float nearestDoubleLevel = na // Explicitly declared as na by default
// Step 1: Identify Swing Highs/Lows
swingHigh = ta.pivothigh(high, leftBars, rightBars)
swingLow = ta.pivotlow(low, leftBars, rightBars)
// Today's premarket start (04:00 AM ET)
todayStart := timestamp(syminfo.timezone, year, month, dayofmonth, 4, 0, 0)
// Clear arrays and delete lines on the first bar or new day
if barstate.isfirst or (dayofmonth != dayofmonth and time >= todayStart)
// Delete all existing lines only if arrays are not empty
if array.size(resLines) > 0
for i = array.size(resLines) - 1 to 0
line.delete(array.get(resLines, i))
if array.size(supLines) > 0
for i = array.size(supLines) - 1 to 0
line.delete(array.get(supLines, i))
// Clear arrays
array.clear(resistanceLevels)
array.clear(supportLevels)
array.clear(resistanceCounts)
array.clear(supportCounts)
array.clear(resLines)
array.clear(supLines)
// Reset flags and levels
hasDoubleTop := false
hasDoubleBottom := false
doubleTopLevel := na
doubleBottomLevel := na
nearestDoubleLevel := na // Ensure reset on new day
// Add new swings only if today and after premarket
if not na(swingHigh) and time >= todayStart and dayofmonth == dayofmonth
bool isEqualHigh = false
int peakIndex = -1
float prevLevel = na
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
prevLevel := array.get(resistanceLevels, i)
if math.abs(swingHigh - prevLevel) <= tolerance
isEqualHigh := true
peakIndex := i
break
if isEqualHigh and peakIndex >= 0
array.set(resistanceCounts, peakIndex, array.get(resistanceCounts, peakIndex) + 1)
if array.get(resistanceCounts, peakIndex) == requiredPeaks
hasDoubleTop := true
doubleTopLevel := prevLevel
else
array.push(resistanceLevels, swingHigh)
array.push(resistanceCounts, 1)
line newResLine = line.new(bar_index - rightBars, swingHigh, bar_index, swingHigh, color=color.red, width=2, extend=extend.none)
array.push(resLines, newResLine)
if not na(swingLow) and time >= todayStart and dayofmonth == dayofmonth
bool isEqualLow = false
int peakIndex = -1
float prevLevel = na
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
prevLevel := array.get(supportLevels, i)
if math.abs(swingLow - prevLevel) <= tolerance
isEqualLow := true
peakIndex := i
break
if isEqualLow and peakIndex >= 0
array.set(supportCounts, peakIndex, array.get(supportCounts, peakIndex) + 1)
if array.get(supportCounts, peakIndex) == requiredPeaks
hasDoubleBottom := true
doubleBottomLevel := prevLevel
else
array.push(supportLevels, swingLow)
array.push(supportCounts, 1)
line newSupLine = line.new(bar_index - rightBars, swingLow, bar_index, swingLow, color=color.green, width=2, extend=extend.none)
array.push(supLines, newSupLine)
// Monitor and remove broken levels/lines; reset pattern if the equal level breaks
if array.size(resistanceLevels) > 0
for i = array.size(resistanceLevels) - 1 to 0
float level = array.get(resistanceLevels, i)
if close > level
line.delete(array.get(resLines, i))
array.remove(resLines, i)
array.remove(resistanceLevels, i)
array.remove(resistanceCounts, i)
if level == doubleTopLevel
hasDoubleTop := false
doubleTopLevel := na
nearestDoubleLevel := na // Reset if level breaks
if array.size(supportLevels) > 0
for i = array.size(supportLevels) - 1 to 0
float level = array.get(supportLevels, i)
if close < level
line.delete(array.get(supLines, i))
array.remove(supLines, i)
array.remove(supportLevels, i)
array.remove(supportCounts, i)
if level == doubleBottomLevel
hasDoubleBottom := false
doubleBottomLevel := na
nearestDoubleLevel := na // Reset if level breaks
// Limit arrays (after removals)
if array.size(resistanceLevels) > 10
line oldLine = array.shift(resLines)
line.delete(oldLine)
array.shift(resistanceLevels)
array.shift(resistanceCounts)
if array.size(supportLevels) > 10
line oldLine = array.shift(supLines)
line.delete(oldLine)
array.shift(supportLevels)
array.shift(supportCounts)
// Pattern Signal: 1 only if the exact required number of peaks is met
patternSignal = (hasDoubleTop or hasDoubleBottom) ? 1 : 0
// New: Nearest Double Level Price - Only update if pattern is active today and on current day
if time >= todayStart and dayofmonth == dayofmonth // Restrict to today
if patternSignal == 1 // Only set if pattern is active
if hasDoubleTop and not na(doubleTopLevel)
nearestDoubleLevel := doubleTopLevel
if hasDoubleBottom and not na(doubleBottomLevel)
nearestDoubleLevel := na(nearestDoubleLevel) ? doubleBottomLevel : (math.abs(close - doubleBottomLevel) < math.abs(close - nearestDoubleLevel) ? doubleBottomLevel : nearestDoubleLevel)
else
nearestDoubleLevel := na // Reset to na if no pattern today
else
nearestDoubleLevel := na // Reset for all historical bars
// New: Distance to Nearest Level (using ATR for normalization)
var float atr = ta.atr(atrLength)
var float distanceNormalizedATR = na
if not na(nearestDoubleLevel) and not na(atr) and atr > 0
distanceNormalizedATR := math.abs(close - nearestDoubleLevel) / atr
// Outputs
plot(patternSignal, title="Pattern Signal", color=patternSignal == 1 ? color.purple : na, style=plot.style_circles)
plot(nearestDoubleLevel, title="Nearest Double Level Price", color=color.orange)
plot(distanceNormalizedATR, title="Normalized Distance (ATR)", color=color.green)
bgcolor(patternSignal == 1 ? color.new(color.purple, 80) : na)
if patternSignal == 1 and barstate.isconfirmed
alert("Double Pattern detected on " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)
if barstate.islast
var table infoTable = table.new(position.top_right, 1, 3, bgcolor=color.new(color.black, 50))
table.cell(infoTable, 0, 0, "Pattern: " + str.tostring(patternSignal), bgcolor=patternSignal == 1 ? color.purple : color.gray)
table.cell(infoTable, 0, 1, "Level: " + str.tostring(nearestDoubleLevel, "#.##"), bgcolor=color.orange)
table.cell(infoTable, 0, 2, "ATR Dist: " + str.tostring(distanceNormalizedATR, "#.##"), bgcolor=color.green)
Double Top/Bottom Screener - Today Only v3 //@version=6
indicator("Double Top/Bottom Screener - Today Only", overlay=true, max_lines_count=500)
// Inputs
leftBars = input.int(5, "Left Bars")
rightBars = input.int(5, "Right Bars")
tolerance = input.float(0.02, "Max Difference (e.g., 0.02 for 2 cents)", step=0.01)
atrLength = input.int(14, "ATR Length for Normalized Distance", minval=1)
requiredPeaks = input.int(3, "Required Identical Peaks", minval=2, maxval=5)
// Declarations of persistent variables and arrays
var array resistanceLevels = array.new(0)
var array resistanceCounts = array.new(0)
var array supportLevels = array.new(0)
var array supportCounts = array.new(0)
var array resLines = array.new(0)
var array supLines = array.new(0)
var bool hasDoubleTop = false
var bool hasDoubleBottom = false
var float doubleTopLevel = na
var float doubleBottomLevel = na
var int todayStart = na
var float nearestDoubleLevel = na // Explicitly declared as na by default
// Step 1: Identify Swing Highs/Lows
swingHigh = ta.pivothigh(high, leftBars, rightBars)
swingLow = ta.pivotlow(low, leftBars, rightBars)
// Today's premarket start (04:00 AM ET)
todayStart := timestamp(syminfo.timezone, year, month, dayofmonth, 4, 0, 0)
// Clear arrays and delete lines on the first bar or new day
if barstate.isfirst or (dayofmonth != dayofmonth and time >= todayStart)
// Delete all existing lines only if arrays are not empty
if array.size(resLines) > 0
for i = array.size(resLines) - 1 to 0
line.delete(array.get(resLines, i))
if array.size(supLines) > 0
for i = array.size(supLines) - 1 to 0
line.delete(array.get(supLines, i))
// Clear arrays
array.clear(resistanceLevels)
array.clear(supportLevels)
array.clear(resistanceCounts)
array.clear(supportCounts)
array.clear(resLines)
array.clear(supLines)
// Reset flags and levels
hasDoubleTop := false
hasDoubleBottom := false
doubleTopLevel := na
doubleBottomLevel := na
nearestDoubleLevel := na // Ensure reset on new day
// Add new swings only if today and after premarket
if not na(swingHigh) and time >= todayStart and dayofmonth == dayofmonth
bool isEqualHigh = false
int peakIndex = -1
float prevLevel = na
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
prevLevel := array.get(resistanceLevels, i)
if math.abs(swingHigh - prevLevel) <= tolerance
isEqualHigh := true
peakIndex := i
break
if isEqualHigh and peakIndex >= 0
array.set(resistanceCounts, peakIndex, array.get(resistanceCounts, peakIndex) + 1)
if array.get(resistanceCounts, peakIndex) == requiredPeaks
hasDoubleTop := true
doubleTopLevel := prevLevel
else
array.push(resistanceLevels, swingHigh)
array.push(resistanceCounts, 1)
line newResLine = line.new(bar_index - rightBars, swingHigh, bar_index, swingHigh, color=color.red, width=2, extend=extend.none)
array.push(resLines, newResLine)
if not na(swingLow) and time >= todayStart and dayofmonth == dayofmonth
bool isEqualLow = false
int peakIndex = -1
float prevLevel = na
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
prevLevel := array.get(supportLevels, i)
if math.abs(swingLow - prevLevel) <= tolerance
isEqualLow := true
peakIndex := i
break
if isEqualLow and peakIndex >= 0
array.set(supportCounts, peakIndex, array.get(supportCounts, peakIndex) + 1)
if array.get(supportCounts, peakIndex) == requiredPeaks
hasDoubleBottom := true
doubleBottomLevel := prevLevel
else
array.push(supportLevels, swingLow)
array.push(supportCounts, 1)
line newSupLine = line.new(bar_index - rightBars, swingLow, bar_index, swingLow, color=color.green, width=2, extend=extend.none)
array.push(supLines, newSupLine)
// Monitor and remove broken levels/lines; reset pattern if the equal level breaks
if array.size(resistanceLevels) > 0
for i = array.size(resistanceLevels) - 1 to 0
float level = array.get(resistanceLevels, i)
if close > level
line.delete(array.get(resLines, i))
array.remove(resLines, i)
array.remove(resistanceLevels, i)
array.remove(resistanceCounts, i)
if level == doubleTopLevel
hasDoubleTop := false
doubleTopLevel := na
nearestDoubleLevel := na // Reset if level breaks
if array.size(supportLevels) > 0
for i = array.size(supportLevels) - 1 to 0
float level = array.get(supportLevels, i)
if close < level
line.delete(array.get(supLines, i))
array.remove(supLines, i)
array.remove(supportLevels, i)
array.remove(supportCounts, i)
if level == doubleBottomLevel
hasDoubleBottom := false
doubleBottomLevel := na
nearestDoubleLevel := na // Reset if level breaks
// Limit arrays (after removals)
if array.size(resistanceLevels) > 10
line oldLine = array.shift(resLines)
line.delete(oldLine)
array.shift(resistanceLevels)
array.shift(resistanceCounts)
if array.size(supportLevels) > 10
line oldLine = array.shift(supLines)
line.delete(oldLine)
array.shift(supportLevels)
array.shift(supportCounts)
// Pattern Signal: 1 only if the exact required number of peaks is met
patternSignal = (hasDoubleTop or hasDoubleBottom) ? 1 : 0
// New: Nearest Double Level Price - Only update if pattern is active today
if time >= todayStart and dayofmonth == dayofmonth // Restrict to today
if (hasDoubleTop and not na(doubleTopLevel)) or (hasDoubleBottom and not na(doubleBottomLevel))
if hasDoubleTop and not na(doubleTopLevel)
nearestDoubleLevel := doubleTopLevel
if hasDoubleBottom and not na(doubleBottomLevel)
nearestDoubleLevel := na(nearestDoubleLevel) ? doubleBottomLevel : (math.abs(close - doubleBottomLevel) < math.abs(close - nearestDoubleLevel) ? doubleBottomLevel : nearestDoubleLevel)
else
nearestDoubleLevel := na // Reset to na if no pattern today
else
nearestDoubleLevel := na // Reset for historical bars
// New: Distance to Nearest Level (using ATR for normalization)
var float atr = ta.atr(atrLength)
var float distanceNormalizedATR = na
if not na(nearestDoubleLevel) and not na(atr) and atr > 0
distanceNormalizedATR := math.abs(close - nearestDoubleLevel) / atr
// Outputs
plot(patternSignal, title="Pattern Signal", color=patternSignal == 1 ? color.purple : na, style=plot.style_circles)
plot(nearestDoubleLevel, title="Nearest Double Level Price", color=color.orange)
plot(distanceNormalizedATR, title="Normalized Distance (ATR)", color=color.green)
bgcolor(patternSignal == 1 ? color.new(color.purple, 80) : na)
if patternSignal == 1 and barstate.isconfirmed
alert("Double Pattern detected on " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)
if barstate.islast
var table infoTable = table.new(position.top_right, 1, 3, bgcolor=color.new(color.black, 50))
table.cell(infoTable, 0, 0, "Pattern: " + str.tostring(patternSignal), bgcolor=patternSignal == 1 ? color.purple : color.gray)
table.cell(infoTable, 0, 1, "Level: " + str.tostring(nearestDoubleLevel, "#.##"), bgcolor=color.orange)
table.cell(infoTable, 0, 2, "ATR Dist: " + str.tostring(distanceNormalizedATR, "#.##"), bgcolor=color.green)